Repository: dice-group/owlapy (language: python)

Issue:
Using Sync as a prefix
What is the purpose of using Sync as a prefix for few classes ?
Rendering owl_datatype_min_max_inclusive_restriction
Could you ensure that the
```python
from owlapy.render import DLSyntaxObjectRenderer
from owlapy.parser import DLSyntaxParser
from owlapy.owl_property import OWLObjectProperty
from owlapy.iri import IRI
from owlapy.owl_data_ranges import OWLDataUnionOf
from owlapy.providers import owl_datatype_min_max_inclusive_restriction
from owlapy.owl_literal import IntegerOWLDatatype
from owlapy.class_expression import OWLDataAllValuesFrom

NS = "http://www.benchmark.org/family#"
parser = DLSyntaxParser(NS)
renderer = DLSyntaxObjectRenderer()
has_age = OWLObjectProperty(IRI(NS, 'hasAge'))
c = OWLDataAllValuesFrom(property=has_age, filler=OWLDataUnionOf([owl_datatype_min_max_inclusive_restriction(40, 80), IntegerOWLDatatype]))
rendered_c = renderer.render(c) # ∀ hasAge.(xsd:integer[≥ 40 , ≤ 80] ⊔ xsd:integer)
```
Could you ensure that we obtain ∀ hasAge.(xsd:integer[≥ 40 ⊓  ≤ 80] ⊔ xsd:integer) after the rendering?

Rendering owl_datatype_min_max_inclusive_restriction
Could you ensure that the
```python
from owlapy.render import DLSyntaxObjectRenderer
from owlapy.parser import DLSyntaxParser
from owlapy.owl_property import OWLObjectProperty
from owlapy.iri import IRI
from owlapy.owl_data_ranges import OWLDataUnionOf
from owlapy.providers import owl_datatype_min_max_inclusive_restriction
from owlapy.owl_literal import IntegerOWLDatatype
from owlapy.class_expression import OWLDataAllValuesFrom

NS = "http://www.benchmark.org/family#"
parser = DLSyntaxParser(NS)
renderer = DLSyntaxObjectRenderer()
has_age = OWLObjectProperty(IRI(NS, 'hasAge'))
c = OWLDataAllValuesFrom(property=has_age, filler=OWLDataUnionOf([owl_datatype_min_max_inclusive_restriction(40, 80), IntegerOWLDatatype]))
rendered_c = renderer.render(c) # ∀ hasAge.(xsd:integer[≥ 40 , ≤ 80] ⊔ xsd:integer)
```
Could you ensure that we obtain ∀ hasAge.(xsd:integer[≥ 40 ⊓  ≤ 80] ⊔ xsd:integer) after the rendering?



Discussion / hints:
Those classes are using _owlapi_ for their functionalities and the idea of "Sync" is that those are synchronizing classes in a sense that nothing is actually implemented in our package and when you are calling a method in python, the actual processing is happening in some java library. Basically its "syncing" our framework with another framework. This naming is not my original idea and is based on a previous naming in owlapy which I believe is based on the naming in owlready2 for a similar functionality.
Yes I thought so. I guess we can start thinking about omitting this prefixing. 


I guess we need some refactroing in the [owl_reasoner.py](https://github.com/dice-group/owlapy/blob/develop/owlapy/owl_reasoner.py)

1. Move AbstractOWLReasonerEx into AbstractOWLReasoner (unclear why these inconvenience needed to be seperated)
2. Delete OntologyReasoner class and 
3. Implement OWLReasoner class

A reasoner should be created as
`reasoner= OWLReasoner(reasoner="Hermit | Pellet .... | FastInstanceCheckerReasoner")`
We might even need to rename `FastInstanceCheckerReasoner`.

Do you think such refactoring would make our interface better ?



Fix patch:
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 10bf2fc9..35d249f7 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -4,7 +4,6 @@ on:
   push:
     branches:
      - main
-     - develop
      - documentation # just for testing
   pull_request:
 
diff --git a/docs/index.rst b/docs/index.rst
index 083391bc..1ab21468 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -14,6 +14,6 @@ Welcome to OWLAPY!
    usage/usage_examples
    usage/ontologies
    usage/reasoner
-   usage/owlapi_adaptor
+   usage/owlapi_synchronization
    usage/further_resources
    autoapi/owlapy/index
\ No newline at end of file
diff --git a/docs/usage/owlapi_adaptor.md b/docs/usage/owlapi_synchronization.md
similarity index 100%
rename from docs/usage/owlapi_adaptor.md
rename to docs/usage/owlapi_synchronization.md
diff --git a/docs/usage/reasoner.md b/docs/usage/reasoner.md
index 33ef9120..63373410 100644
--- a/docs/usage/reasoner.md
+++ b/docs/usage/reasoner.md
@@ -13,87 +13,71 @@ manager = OntologyManager()
 onto = manager.load_ontology(IRI.create("KGs/Family/father.owl"))
 ```
 
-In our Owlapy library, we provide several **reasoners** to choose
-from:
+In our Owlapy library, we provide two main reasoner classes:
 
-- [**OntologyReasoner**](owlapy.owl_reasoner.OntologyReasoner)
 
-    Or differently Structural Reasoner, is the base reasoner in Owlapy. The functionalities
-  of this reasoner are limited. It does not provide full reasoning in _ALCH_. Furthermore,
-  it has no support for instances of complex class expressions, which is covered by the
-  other reasoners (SyncReasoner and FIC). This reasoner is used as
-  a base reasoner for FIC which overwrites the `instances` method. 
-  We recommend using the other reasoners for any reasoning tasks.
+- [**StructuralReasoner**](owlapy.owl_reasoner.StructuralReasoner) (What used to be FastInstanceCheckerReasoner )
 
-    **Initialization:**
+    Structural Reasoner is the base reasoner in Owlapy. This reasoner works 
+   under CWA/PCWA and the base library used for it is _owlready2_. The functionalities
+  of this reasoner are limited and may be incomplete. It does not provide full reasoning in _ALCH_. 
+  It provides support for finding instance of complex class expression.
+  It has a cache storing system that allows for faster execution of some reasoning functionalities.
 
-   ```python
-   from owlapy.owl_reasoner import OntologyReasoner
-   
-   structural_reasoner = OntologyReasoner(onto)
-   ```
+    **Initialization:**
 
-    The structural reasoner requires an ontology ([OWLOntology](owlapy.owl_ontology.OWLOntology)).
+    ```python
+    from owlapy.owl_reasoner import StructuralReasoner
     
+    structural_reasoner = StructuralReasoner(onto, property_cache = True, negation_default = True, sub_properties = False)
+    ```
+  The structural reasoner requires an ontology ([AbstractOWLOntology](owlapy.abstracts.AbstractOWLOntology)).
+  `property_cache` specifies whether to cache property values. This
+  requires more memory, but it speeds up the reasoning processes. If `negation_default` argument is set
+  to `True` the missing facts in the ontology means false. The argument
+    `sub_properties` is another boolean argument to specify whether you want to take sub properties in consideration
+  for `instances()` method.
 
 
 - [**SyncReasoner**](owlapy.owl_reasoner.SyncReasoner)
-
-    Can perform full reasoning in _ALCH_ due to the use of reasoners from 
-  owlapi like HermiT, Pellet, etc. and provides support for
-  complex class expression instances (when using the method `instances`). 
+  
+  SyncReasoner is a class that serves as a 'syncing' class 
+  between our framework and reasoners in _owlapi_. It
+  can perform full reasoning in _ALCH_ due to the use of reasoners from 
+  powerful reasoners like HermiT, Pellet, etc. 
   SyncReasoner is more useful when your main goal is reasoning over the ontology,
-  and you are familiarized with the java reasoners (HermiT, Pellet, ...).
+  and you are familiarized with the java reasoners (HermiT, Pellet, JFact, Openllet, ...).
 
     **Initialization:**
 
     ```python
     from owlapy.owl_reasoner import SyncReasoner
     
-    sync_reasoner = SyncReasoner(ontology_path="KGs/Mutagenesis/mutagenesis.owl", reasoner="HermiT")
+    sync_reasoner = SyncReasoner(ontology="KGs/Mutagenesis/mutagenesis.owl", reasoner="HermiT")
     ```
     
-    Sync Reasoner is made available by [owlapi mapper](owlapi_adaptor.md) and requires the ontology path
-    together with a reasoner name from the possible set of reasoners: `"Hermit"`, `"Pellet"`, `"JFact"`, `"Openllet"`.
-
-
-- [**FastInstanceCheckerReasoner**](owlapy.owl_reasoner.FastInstanceCheckerReasoner) **(FIC)**
-
-    FIC also provides support for complex class expression but the rest of the methods are the same as in
-  the base reasoner.
-  It has a cache storing system that allows for faster execution of some reasoning functionalities. Due to this
-  feature, FIC is more appropriate to be used in concept learning.
-
-    **Initialization:**
-
-    ```python
-    from owlapy.owl_reasoner import FastInstanceCheckerReasoner
-    
-    fic_reasoner = FastInstanceCheckerReasoner(onto, structural_reasoner, property_cache = True,
-                                                   negation_default = True, sub_properties = False)
-    ```
-    Besides the ontology, FIC requires a base reasoner to delegate any reasoning tasks not covered by it.
-  This base reasoner
-  can be any other reasoner in Owlapy (usually it's [OntologyReasoner](owlapy.owl_reasoner.OntologyReasoner)).
-  `property_cache` specifies whether to cache property values. This
-  requires more memory, but it speeds up the reasoning processes. If `negation_default` argument is set
-  to `True` the missing facts in the ontology means false. The argument
-    `sub_properties` is another boolean argument to specify whether you want to take sub properties in consideration
-  for `instances()` method.
+    SyncReasoner is made available by [owlapi mapper](owlapi_synchronization.md) and requires the ontology path or an
+    object of type [SyncOntology](owlapy.owl_ontology.SyncOntology),
+    together with a reasoner name from the possible set of reasoners: `"Hermit"`, `"Pellet"`, `"JFact"`, `"Openllet"`
+   `"StructuralReasoner"`.
+ 
+   
+   **Note that SyncReasoner with `reasoner` argument set to `"StructuralReasoner"` is refering to 
+   _StructuralReasoner_ implemented in owlapi. That is different from our StructuralReasoner.**
 
+  
 ## Usage of the Reasoner
 All the reasoners available in the Owlapy library inherit from the
-class: [OWLReasonerEx](owlapy.owl_reasoner.OWLReasonerEx). This class provides some 
-extra convenient methods compared to its base abstract class [OWLReasoner](owlapy.owl_reasoner.OWLReasoner).
-Further on, in this guide, we use [FastInstanceCheckerReasoner](owlapy.owl_reasoner.FastInstanceCheckerReasoner)
+class: [AbstractOWLReasoner](owlapy.abstracts.AbstractOWLReasoner).
+Further on, in this guide, we use [StructuralReasoner](owlapy.owl_reasoner.StructuralReasoner)
 to show the capabilities of a reasoner in Owlapy.
 
-As mentioned earlier we will use the _father_ dataset to give examples.
+We will proceed to use the _father_ dataset to give examples.
 
 
 ## Class Reasoning
 
-Using an [OWLOntology](owlapy.owl_ontology.OWLOntology) you can list all the classes in the signature, 
+Using an [AbstractOWLOntology](owlapy.abstracts.AbstractOWLOntology) you can list all the classes in the signature, 
 but a reasoner can give you more than that. You can get the subclasses, superclasses or the 
 equivalent classes of a class in the ontology:
 
@@ -106,9 +90,9 @@ from owlapy.iri import IRI
 namespace = "http://example.com/father#"
 male = OWLClass(IRI(namespace, "male"))
 
-male_super_classes = fic_reasoner.super_classes(male)
-male_sub_classes = fic_reasoner.sub_classes(male)
-male_equivalent_classes = fic_reasoner.equivalent_classes(male)
+male_super_classes = structural_reasoner.super_classes(male)
+male_sub_classes = structural_reasoner.sub_classes(male)
+male_equivalent_classes = structural_reasoner.equivalent_classes(male)
 ```
 
 We define the _male_ class by creating an [OWLClass](owlapy.class_expression.owl_class.OWLClass) object. The 
@@ -124,9 +108,8 @@ means that it will return only the named classes.
 >**NOTE**: The extra arguments `direct` and `only_named` are also used in other methods that reason
 upon the class, object property, or data property hierarchy.
 
->**NOTE**: SyncReasoner implements OWLReasoner where we can specify the `only_named` argument
-> in some methods but in java reasoners there is no use for such argument and therefore this
-> argument is trivial when used in SyncReasoner's methods. 
+>**NOTE**: In SyncReasoner, there is no use for the argument `only_named` as this is not
+> supported by methods in the java library owlapi. 
 
 You can get all the types of a certain individual using `types` method:
 
@@ -135,7 +118,7 @@ You can get all the types of a certain individual using `types` method:
 ```python
 anna = list(onto.individuals_in_signature()).pop(0)
 
-anna_types = fic_reasoner.types(anna)
+anna_types = structural_reasoner.types(anna)
 ```
 
 We retrieve _anna_ as the first individual on the list of individuals 
@@ -145,7 +128,7 @@ of the 'Father' ontology. The `type` method only returns named classes.
 ## Object Properties and Data Properties Reasoning
 Owlapy reasoners offers some convenient methods for working with object properties and 
 data properties. Below we show some of them, but you can always check all the methods in the 
-[OWLReasoner](owlapy.owl_reasoner.OWLReasoner)
+[AbstractOWLReasoner](owlapy.abstracts.AbstractOWLReasoner)
 class documentation. 
 
 You can get all the object properties that an individual has by using the 
@@ -154,7 +137,7 @@ following method:
 <!--pytest-codeblocks:cont-->
 ```python
 anna = individuals[0] 
-object_properties = fic_reasoner.ind_object_properties(anna)
+object_properties = structural_reasoner.ind_object_properties(anna)
 ```
 In this example, `object_properties` contains all the object properties
 that _anna_ has, which in our case would only be _hasChild_.
@@ -163,7 +146,7 @@ Now we can get the individuals of this object property for _anna_.
 <!--pytest-codeblocks:cont-->
 ```python
 for op in object_properties:
-    object_properties_values = fic_reasoner.object_property_values(anna, op)
+    object_properties_values = structural_reasoner.object_property_values(anna, op)
     for individual in object_properties_values:
         print(individual)
 ```
@@ -191,16 +174,16 @@ from owlapy.owl_property import OWLObjectProperty
 
 hasChild = OWLObjectProperty(IRI(namespace, "hasChild"))
 
-equivalent_to_hasChild = fic_reasoner.equivalent_object_properties(hasChild)
-hasChild_sub_properties = fic_reasoner.sub_object_properties(hasChild)
+equivalent_to_hasChild = structural_reasoner.equivalent_object_properties(hasChild)
+hasChild_sub_properties = structural_reasoner.sub_object_properties(hasChild)
 ```
 
 In case you want to get the domains and ranges of an object property use the following:
 
 <!--pytest-codeblocks:cont-->
 ```python
-hasChild_domains = fic_reasoner.object_property_domains(hasChild)
-hasChild_ranges = fic_reasoner.object_property_ranges(hasChild)
+hasChild_domains = structural_reasoner.object_property_domains(hasChild)
+hasChild_ranges = structural_reasoner.object_property_ranges(hasChild)
 ```
 
 > **NOTE:** Again, you can do the same for data properties but instead of the word 'object' in the 
@@ -218,7 +201,7 @@ Let us now show a simple example by finding the instances of the class _male_ an
 
 <!--pytest-codeblocks:cont-->
 ```python
-male_individuals = fic_reasoner.instances(male)
+male_individuals = structural_reasoner.instances(male)
 for ind in male_individuals:
     print(ind)
 ```
@@ -226,7 +209,7 @@ for ind in male_individuals:
 -----------------------------------------------------------------------
 
 In this guide we covered the main functionalities of the reasoners in Owlapy. 
-In the next one, we speak about owlapi adaptor and how can make use of owlapi in owlapy.
+In the next one, we speak about owlapi synchronization and how can make use of owlapi in owlapy.
 
 
 
diff --git a/examples/ontology_reasoning.py b/examples/ontology_reasoning.py
index dd12db7f..5a015d74 100644
--- a/examples/ontology_reasoning.py
+++ b/examples/ontology_reasoning.py
@@ -4,7 +4,7 @@
 from owlapy.owl_individual import OWLNamedIndividual
 from owlapy.owl_ontology_manager import OntologyManager
 from owlapy.owl_property import OWLDataProperty, OWLObjectProperty
-from owlapy.owl_reasoner import OntologyReasoner, FastInstanceCheckerReasoner
+from owlapy.owl_reasoner import StructuralReasoner
 
 data_file = '../KGs/Test/test_ontology.owl'
 NS = 'http://www.semanticweb.org/stefan/ontologies/2023/1/untitled-ontology-11#'
@@ -126,11 +126,10 @@
 onto.add_axiom(OWLSubClassOfAxiom(R, r5Q))
 onto.add_axiom(OWLSubClassOfAxiom(ST, U))
 
-base_reasoner = OntologyReasoner(onto)
 
 # ---------------------------------------- Reasoning ----------------------------------------
 
-reasoner = FastInstanceCheckerReasoner(onto, base_reasoner)
+reasoner = StructuralReasoner(onto)
 
 # Instances
 t1 = list(reasoner.instances(N))
diff --git a/owlapy/abstracts/__init__.py b/owlapy/abstracts/__init__.py
index 49b5a7ab..3d223eb2 100644
--- a/owlapy/abstracts/__init__.py
+++ b/owlapy/abstracts/__init__.py
@@ -1,5 +1,4 @@
 from .abstract_owl_ontology_manager import AbstractOWLOntologyManager, AbstractOWLOntologyChange, AbstractOWLOntology
-from .abstract_owl_reasoner import AbstractOWLReasoner, AbstractOWLReasonerEx
+from .abstract_owl_reasoner import AbstractOWLReasoner
 
-__all__ = ['AbstractOWLOntologyManager', 'AbstractOWLOntologyChange', 'AbstractOWLOntology', 'AbstractOWLReasoner',
-           'AbstractOWLReasonerEx']
+__all__ = ['AbstractOWLOntologyManager', 'AbstractOWLOntologyChange', 'AbstractOWLOntology', 'AbstractOWLReasoner']
diff --git a/owlapy/abstracts/abstract_owl_reasoner.py b/owlapy/abstracts/abstract_owl_reasoner.py
index 987c3f2a..c5ba3005 100644
--- a/owlapy/abstracts/abstract_owl_reasoner.py
+++ b/owlapy/abstracts/abstract_owl_reasoner.py
@@ -377,11 +377,6 @@ class expression with respect to the imports closure of the root ontology.
         """
         pass
 
-
-class AbstractOWLReasonerEx(AbstractOWLReasoner, metaclass=ABCMeta):
-    """Extra convenience methods for OWL Reasoners"""
-
-    # default
     def data_property_ranges(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataRange]:
         """Gets the data ranges that are the direct or indirect ranges of this property with respect to the imports
         closure of the root ontology.
diff --git a/owlapy/owl_ontology.py b/owlapy/owl_ontology.py
index 683a947b..d527383e 100644
--- a/owlapy/owl_ontology.py
+++ b/owlapy/owl_ontology.py
@@ -779,11 +779,12 @@ def _(axiom: OWLDataPropertyCharacteristicAxiom, ontology: AbstractOWLOntology,
 
 
 class Ontology(AbstractOWLOntology):
-    __slots__ = '_manager', '_iri', '_world', '_onto'
+    __slots__ = '_manager', '_iri', '_world', '_onto', 'is_modified'
 
     _manager: _OM
     _onto: owlready2.Ontology
     _world: owlready2.World
+    is_modified: bool
 
     def __init__(self, manager: _OM, ontology_iri: IRI, load: bool):
         """Represents an Ontology in Ontolearn.
@@ -796,6 +797,7 @@ def __init__(self, manager: _OM, ontology_iri: IRI, load: bool):
         self._manager = manager
         self._iri = ontology_iri
         self._world = manager._world
+        self.is_modified = False
         onto = self._world.get_ontology(ontology_iri.as_str())
         if load:
             onto = onto.load()
@@ -919,6 +921,7 @@ def object_property_range_axioms(self, pe: OWLObjectProperty) -> Iterable[OWLObj
                     pass  # XXX TODO
 
     def add_axiom(self, axiom: Union[OWLAxiom, Iterable[OWLAxiom]]):
+        self.is_modified = True
         if isinstance(axiom, OWLAxiom):
             _add_axiom(axiom, self, self._world)
         else:
@@ -926,6 +929,7 @@ def add_axiom(self, axiom: Union[OWLAxiom, Iterable[OWLAxiom]]):
                 _add_axiom(ax, self, self._world)
 
     def remove_axiom(self, axiom: Union[OWLAxiom, Iterable[OWLAxiom]]):
+        self.is_modified = True
         if isinstance(axiom, OWLAxiom):
             _remove_axiom(axiom, self, self._world)
         else:
diff --git a/owlapy/owl_reasoner.py b/owlapy/owl_reasoner.py
index 5dd6998b..211460d9 100644
--- a/owlapy/owl_reasoner.py
+++ b/owlapy/owl_reasoner.py
@@ -17,7 +17,7 @@
 from owlapy.class_expression import OWLClass
 from owlapy.iri import IRI
 from owlapy.owl_axiom import OWLAxiom, OWLSubClassOfAxiom
-from owlapy.owl_data_ranges import OWLDataRange, OWLDataComplementOf, OWLDataUnionOf, OWLDataIntersectionOf
+from owlapy.owl_data_ranges import OWLDataComplementOf, OWLDataUnionOf, OWLDataIntersectionOf
 from owlapy.owl_datatype import OWLDatatype
 from owlapy.owl_object import OWLEntity
 from owlapy.owl_ontology import Ontology, _parse_concept_to_owlapy, SyncOntology
@@ -28,29 +28,91 @@
 from owlapy.owl_individual import OWLNamedIndividual
 from owlapy.owl_literal import OWLLiteral
 from owlapy.utils import LRUCache, run_with_timeout
-from owlapy.abstracts.abstract_owl_reasoner import AbstractOWLReasoner, AbstractOWLReasonerEx
+from owlapy.abstracts.abstract_owl_reasoner import AbstractOWLReasoner
 logger = logging.getLogger(__name__)
 
 _P = TypeVar('_P', bound=OWLPropertyExpression)
 
-class OntologyReasoner(AbstractOWLReasonerEx):
-    __slots__ = '_ontology', '_world'
-    # TODO: CD: We will remove owlready2 from owlapy
+
+class StructuralReasoner(AbstractOWLReasoner):
+    """Tries to check instances fast (but maybe incomplete)."""
+    __slots__ = '_ontology', '_world', \
+                '_ind_set', '_cls_to_ind', \
+                '_has_prop', 'class_cache', \
+                '_objectsomevalues_cache', '_datasomevalues_cache', '_objectcardinality_cache', \
+                '_property_cache', \
+                '_obj_prop', '_obj_prop_inv', '_data_prop', \
+                '_negation_default', '_sub_properties', \
+                '__warned'
+
     _ontology: Ontology
     _world: owlready2.World
+    _cls_to_ind: Dict[OWLClass, FrozenSet[OWLNamedIndividual]]  # Class => individuals
+    _has_prop: Mapping[Type[_P], LRUCache[_P, FrozenSet[OWLNamedIndividual]]]  # Type => Property => individuals
+    _ind_set: FrozenSet[OWLNamedIndividual]
+    # ObjectSomeValuesFrom => individuals
+    _objectsomevalues_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
+    # DataSomeValuesFrom => individuals
+    _datasomevalues_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
+    # ObjectCardinalityRestriction => individuals
+    _objectcardinality_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
+    # ObjectProperty => { individual => individuals }
+    _obj_prop: Dict[OWLObjectProperty, Mapping[OWLNamedIndividual, Set[OWLNamedIndividual]]]
+    # ObjectProperty => { individual => individuals }
+    _obj_prop_inv: Dict[OWLObjectProperty, Mapping[OWLNamedIndividual, Set[OWLNamedIndividual]]]
+    # DataProperty => { individual => literals }
+    _data_prop: Dict[OWLDataProperty, Mapping[OWLNamedIndividual, Set[OWLLiteral]]]
+    class_cache: bool
+    _property_cache: bool
+    _negation_default: bool
+    _sub_properties: bool
 
-    def __init__(self, ontology: Ontology):
-        """
-        Base reasoner in Ontolearn, used to reason in the given ontology.
+    def __init__(self, ontology: AbstractOWLOntology, *, class_cache: bool = True,
+                 property_cache: bool = True, negation_default: bool = True, sub_properties: bool = False):
+        """Fast instance checker.
 
         Args:
-            ontology: The ontology that should be used by the reasoner.
-        """
+            ontology: Ontology to use.
+            property_cache: Whether to cache property values.
+            negation_default: Whether to assume a missing fact means it is false ("closed world view").
+            sub_properties: Whether to take sub properties into account for the
+                :func:`StructuralReasoner.instances` retrieval.
+            """
         super().__init__(ontology)
         assert isinstance(ontology, Ontology)
-        self._isolated = False
-        self._ontology = ontology
         self._world = ontology._world
+        self._ontology = ontology
+        self.class_cache = class_cache
+        self._property_cache = property_cache
+        self._negation_default = negation_default
+        self._sub_properties = sub_properties
+        self.__warned = 0
+        self._init()
+
+    def _init(self, cache_size=128):
+
+        individuals = self._ontology.individuals_in_signature()
+        self._ind_set = frozenset(individuals)
+        self._objectsomevalues_cache = LRUCache(maxsize=cache_size)
+        self._datasomevalues_cache = LRUCache(maxsize=cache_size)
+        self._objectcardinality_cache = LRUCache(maxsize=cache_size)
+        if self.class_cache:
+            self._cls_to_ind = dict()
+
+        if self._property_cache:
+            self._obj_prop = dict()
+            self._obj_prop_inv = dict()
+            self._data_prop = dict()
+        else:
+            self._has_prop = MappingProxyType({
+                OWLDataProperty: LRUCache(maxsize=cache_size),
+                OWLObjectProperty: LRUCache(maxsize=cache_size),
+                OWLObjectInverseOf: LRUCache(maxsize=cache_size),
+            })
+
+    def reset(self):
+        """The reset method shall reset any cached state."""
+        self._init()
 
     def data_property_domains(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLClassExpression]:
         domains = {d.get_domain() for d in self.get_root_ontology().data_property_domain_axioms(pe)}
@@ -198,31 +260,11 @@ def object_property_values(self, ind: OWLNamedIndividual, pe: OWLObjectPropertyE
 
     def _instances(self, ce: OWLClassExpression, direct: bool = False) -> Iterable[OWLNamedIndividual]:
         if direct:
-            if isinstance(ce, OWLClass):
-                c_x: owlready2.ThingClass = self._world[ce.str]
-                for i in self._ontology._onto.get_instances_of(c_x):
-                    if isinstance(i, owlready2.Thing):
-                        yield OWLNamedIndividual(IRI.create(i.iri))
-            else:
-                raise NotImplementedError("instances for complex class expressions not implemented", ce)
-        else:
-            if ce.is_owl_thing():
-                yield from self._ontology.individuals_in_signature()
-            elif isinstance(ce, OWLClass):
-                c_x: owlready2.ThingClass = self._world[ce.str]
-                for i in c_x.instances(world=self._world):
-                    if isinstance(i, owlready2.Thing):
-                        yield OWLNamedIndividual(IRI.create(i.iri))
-            # elif isinstance(ce, OWLObjectSomeValuesFrom) and ce.get_filler().is_owl_thing()\
-            #         and isinstance(ce.get_property(), OWLProperty):
-            #     seen_set = set()
-            #     p_x: owlready2.ObjectProperty = self._world[ce.get_property().get_named_property().str]
-            #     for i, _ in p_x.get_relations():
-            #         if isinstance(i, owlready2.Thing) and i not in seen_set:
-            #             seen_set.add(i)
-            #             yield OWLNamedIndividual(IRI.create(i.iri))
-            else:
-                raise NotImplementedError("instances for complex class expressions not implemented", ce)
+            if not self.__warned & 2:
+                logger.warning("direct not implemented")
+                self.__warned |= 2
+        temp = self._find_instances(ce)
+        yield from temp
 
     def instances(self, ce: OWLClassExpression, direct: bool = False, timeout: int = 1000):
         return run_with_timeout(self._instances, timeout, (ce, direct))
@@ -556,188 +598,6 @@ def types(self, ind: OWLNamedIndividual, direct: bool = False) -> Iterable[OWLCl
                     yield OWLClass(IRI.create(c.iri))
                 # Anonymous classes are ignored
 
-    # Deprecated
-    # def _sync_reasoner(self, other_reasoner: BaseReasoner = None,
-    #                    infer_property_values: bool = True,
-    #                    infer_data_property_values: bool = True, debug: bool = False) -> None:
-    #     """Call Owlready2's sync_reasoner method, which spawns a Java process on a temp file to infer more.
-    #
-    #     Args:
-    #         other_reasoner: Set to BaseReasoner.PELLET (default) or BaseReasoner.HERMIT.
-    #         infer_property_values: Whether to infer property values.
-    #         infer_data_property_values: Whether to infer data property values (only for PELLET).
-    #     """
-    #     assert other_reasoner is None or isinstance(other_reasoner, BaseReasoner)
-    #     with self.get_root_ontology()._onto:
-    #         if other_reasoner == BaseReasoner.HERMIT:
-    #             owlready2.sync_reasoner_hermit(self._world, infer_property_values=infer_property_values, debug=debug)
-    #         else:
-    #             owlready2.sync_reasoner_pellet(self._world,
-    #                                            infer_property_values=infer_property_values,
-    #                                            infer_data_property_values=infer_data_property_values,
-    #                                            debug=debug)
-
-    def get_root_ontology(self) -> AbstractOWLOntology:
-        return self._ontology
-
-
-class FastInstanceCheckerReasoner(AbstractOWLReasonerEx):
-    """Tries to check instances fast (but maybe incomplete)."""
-    __slots__ = '_ontology', '_base_reasoner', \
-                '_ind_set', '_cls_to_ind', \
-                '_has_prop', \
-                '_objectsomevalues_cache', '_datasomevalues_cache', '_objectcardinality_cache', \
-                '_property_cache', \
-                '_obj_prop', '_obj_prop_inv', '_data_prop', \
-                '_negation_default', \
-                '__warned'
-
-    _ontology: AbstractOWLOntology
-    _base_reasoner: AbstractOWLReasoner
-    _cls_to_ind: Dict[OWLClass, FrozenSet[OWLNamedIndividual]]  # Class => individuals
-    _has_prop: Mapping[Type[_P], LRUCache[_P, FrozenSet[OWLNamedIndividual]]]  # Type => Property => individuals
-    _ind_set: FrozenSet[OWLNamedIndividual]
-    # ObjectSomeValuesFrom => individuals
-    _objectsomevalues_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
-    # DataSomeValuesFrom => individuals
-    _datasomevalues_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
-    # ObjectCardinalityRestriction => individuals
-    _objectcardinality_cache: LRUCache[OWLClassExpression, FrozenSet[OWLNamedIndividual]]
-    # ObjectProperty => { individual => individuals }
-    _obj_prop: Dict[OWLObjectProperty, Mapping[OWLNamedIndividual, Set[OWLNamedIndividual]]]
-    # ObjectProperty => { individual => individuals }
-    _obj_prop_inv: Dict[OWLObjectProperty, Mapping[OWLNamedIndividual, Set[OWLNamedIndividual]]]
-    # DataProperty => { individual => literals }
-    _data_prop: Dict[OWLDataProperty, Mapping[OWLNamedIndividual, Set[OWLLiteral]]]
-    _property_cache: bool
-    _negation_default: bool
-    _sub_properties: bool
-
-    def __init__(self, ontology: AbstractOWLOntology, base_reasoner: AbstractOWLReasoner, *,
-                 property_cache: bool = True, negation_default: bool = True, sub_properties: bool = False):
-        """Fast instance checker.
-
-        Args:
-            ontology: Ontology to use.
-            base_reasoner: Reasoner to get instances/types from.
-            property_cache: Whether to cache property values.
-            negation_default: Whether to assume a missing fact means it is false ("closed world view").
-            sub_properties: Whether to take sub properties into account for the
-                :func:`OWLReasoner_FastInstanceChecker.instances` retrieval.
-            """
-        super().__init__(ontology)
-        self._ontology = ontology
-        self._base_reasoner = base_reasoner
-        self._property_cache = property_cache
-        self._negation_default = negation_default
-        self._sub_properties = sub_properties
-        self.__warned = 0
-        self._init()
-
-    def _init(self, cache_size=128):
-        self._cls_to_ind = dict()
-        individuals = self._ontology.individuals_in_signature()
-        self._ind_set = frozenset(individuals)
-        self._objectsomevalues_cache = LRUCache(maxsize=cache_size)
-        self._datasomevalues_cache = LRUCache(maxsize=cache_size)
-        self._objectcardinality_cache = LRUCache(maxsize=cache_size)
-        if self._property_cache:
-            self._obj_prop = dict()
-            self._obj_prop_inv = dict()
-            self._data_prop = dict()
-        else:
-            self._has_prop = MappingProxyType({
-                OWLDataProperty: LRUCache(maxsize=cache_size),
-                OWLObjectProperty: LRUCache(maxsize=cache_size),
-                OWLObjectInverseOf: LRUCache(maxsize=cache_size),
-            })
-
-    def reset(self):
-        """The reset method shall reset any cached state."""
-        self._init()
-
-    def data_property_domains(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLClassExpression]:
-        yield from self._base_reasoner.data_property_domains(pe, direct=direct)
-
-    def data_property_ranges(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataRange]:
-        yield from self._base_reasoner.data_property_ranges(pe, direct=direct)
-
-    def object_property_domains(self, pe: OWLObjectProperty, direct: bool = False) -> Iterable[OWLClassExpression]:
-        yield from self._base_reasoner.object_property_domains(pe, direct=direct)
-
-    def object_property_ranges(self, pe: OWLObjectProperty, direct: bool = False) -> Iterable[OWLClassExpression]:
-        yield from self._base_reasoner.object_property_ranges(pe, direct=direct)
-
-    def equivalent_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]:
-        yield from self._base_reasoner.equivalent_classes(ce, only_named=only_named)
-
-    def disjoint_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]:
-        yield from self._base_reasoner.disjoint_classes(ce, only_named=only_named)
-
-    def different_individuals(self, ce: OWLNamedIndividual) -> Iterable[OWLNamedIndividual]:
-        yield from self._base_reasoner.different_individuals(ce)
-
-    def same_individuals(self, ce: OWLNamedIndividual) -> Iterable[OWLNamedIndividual]:
-        yield from self._base_reasoner.same_individuals(ce)
-
-    def data_property_values(self, e: OWLEntity, pe: OWLDataProperty, direct: bool = True) \
-            -> Iterable[OWLLiteral]:
-        yield from self._base_reasoner.data_property_values(e, pe, direct)
-
-    def all_data_property_values(self, pe: OWLDataProperty, direct: bool = True) -> Iterable[OWLLiteral]:
-        yield from self._base_reasoner.all_data_property_values(pe, direct)
-
-    def object_property_values(self, ind: OWLNamedIndividual, pe: OWLObjectPropertyExpression, direct: bool = True) \
-            -> Iterable[OWLNamedIndividual]:
-        yield from self._base_reasoner.object_property_values(ind, pe, direct)
-
-    def _instances(self, ce: OWLClassExpression, direct: bool = False) -> Iterable[OWLNamedIndividual]:
-        if direct:
-            if not self.__warned & 2:
-                logger.warning("direct not implemented")
-                self.__warned |= 2
-        temp = self._find_instances(ce)
-        yield from temp
-
-    def instances(self, ce: OWLClassExpression, direct: bool = False, timeout: int = 1000):
-        return run_with_timeout(self._instances, timeout, (ce, direct))
-
-    def sub_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \
-            -> Iterable[OWLClassExpression]:
-        yield from self._base_reasoner.sub_classes(ce, direct=direct, only_named=only_named)
-
-    def super_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \
-            -> Iterable[OWLClassExpression]:
-        yield from self._base_reasoner.super_classes(ce, direct=direct, only_named=only_named)
-
-    def types(self, ind: OWLNamedIndividual, direct: bool = False) -> Iterable[OWLClass]:
-        yield from self._base_reasoner.types(ind, direct=direct)
-
-    def equivalent_object_properties(self, dp: OWLObjectPropertyExpression) -> Iterable[OWLObjectPropertyExpression]:
-        yield from self._base_reasoner.equivalent_object_properties(dp)
-
-    def equivalent_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataProperty]:
-        yield from self._base_reasoner.equivalent_data_properties(dp)
-
-    def disjoint_object_properties(self, dp: OWLObjectPropertyExpression) -> Iterable[OWLObjectPropertyExpression]:
-        yield from self._base_reasoner.disjoint_object_properties(dp)
-
-    def disjoint_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataProperty]:
-        yield from self._base_reasoner.disjoint_data_properties(dp)
-
-    def sub_data_properties(self, dp: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataProperty]:
-        yield from self._base_reasoner.sub_data_properties(dp=dp, direct=direct)
-
-    def super_data_properties(self, dp: OWLDataProperty, direct: bool = False) -> Iterable[OWLDataProperty]:
-        yield from self._base_reasoner.super_data_properties(dp=dp, direct=direct)
-
-    def super_object_properties(self, op: OWLObjectProperty, direct: bool = False) -> Iterable[OWLDataProperty]:
-        yield from self._base_reasoner.super_object_properties(op=op, direct=direct)
-
-    def sub_object_properties(self, op: OWLObjectPropertyExpression, direct: bool = False) \
-            -> Iterable[OWLObjectPropertyExpression]:
-        yield from self._base_reasoner.sub_object_properties(op=op, direct=direct)
-
     def get_root_ontology(self) -> AbstractOWLOntology:
         return self._ontology
 
@@ -777,7 +637,7 @@ def _lazy_cache_obj_prop(self, pe: OWLObjectPropertyExpression) -> None:
                     opc[s] |= {o}
         else:
             for s in self._ind_set:
-                individuals = set(self._base_reasoner.object_property_values(s, pe, not self._sub_properties))
+                individuals = set(self.object_property_values(s, pe, not self._sub_properties))
                 if individuals:
                     opc[s] = individuals
 
@@ -813,9 +673,9 @@ def _some_values_subject_index(self, pe: OWLPropertyExpression) -> FrozenSet[OWL
                         subs |= {OWLNamedIndividual(IRI.create(l_x.iri))}
             else:
                 if isinstance(pe, OWLDataProperty):
-                    func = self._base_reasoner.data_property_values
+                    func = self.data_property_values
                 else:
-                    func = self._base_reasoner.object_property_values
+                    func = self.object_property_values
 
                 for s in self._ind_set:
                     try:
@@ -832,7 +692,8 @@ def _find_some_values(self, pe: OWLObjectPropertyExpression, filler_inds: Set[OW
                           min_count: int = 1, max_count: Optional[int] = None) -> FrozenSet[OWLNamedIndividual]:
         """Get all individuals that have one of filler_inds as their object property value."""
         ret = set()
-
+        if self._ontology.is_modified and (self.class_cache or self._property_cache):
+            self.reset_and_disable_cache()
         if self._property_cache:
             self._lazy_cache_obj_prop(pe)
 
@@ -858,7 +719,7 @@ def _find_some_values(self, pe: OWLObjectPropertyExpression, filler_inds: Set[OW
 
             for s in subs:
                 count = 0
-                for o in self._base_reasoner.object_property_values(s, pe, not self._sub_properties):
+                for o in self.object_property_values(s, pe, not self._sub_properties):
                     if {o} & filler_inds:
                         count = count + 1
                         if max_count is None and count >= min_count:
@@ -890,7 +751,7 @@ def _lazy_cache_data_prop(self, pe: OWLDataPropertyExpression) -> None:
                     opc[s].add(o_literal)
         else:
             for s in self._ind_set:
-                values = set(self._base_reasoner.data_property_values(s, pe))
+                values = set(self.data_property_values(s, pe))
                 if len(values) > 0:
                     opc[s] = values
 
@@ -903,8 +764,13 @@ def _find_instances(self, ce: OWLClassExpression) -> FrozenSet[OWLNamedIndividua
 
     @_find_instances.register
     def _(self, c: OWLClass) -> FrozenSet[OWLNamedIndividual]:
-        self._lazy_cache_class(c)
-        return self._cls_to_ind[c]
+        if self._ontology.is_modified and (self.class_cache or self._property_cache):
+            self.reset_and_disable_cache()
+        if self.class_cache:
+            self._lazy_cache_class(c)
+            return self._cls_to_ind[c]
+        else:
+            return frozenset(self.get_instances_from_owl_class(c))
 
     @_find_instances.register
     def _(self, ce: OWLObjectUnionOf) -> FrozenSet[OWLNamedIndividual]:
@@ -1016,8 +882,9 @@ def _(self, ce: OWLDataSomeValuesFrom) -> FrozenSet[OWLNamedIndividual]:
         pe = ce.get_property()
         filler = ce.get_filler()
         assert isinstance(pe, OWLDataProperty)
-        #
 
+        if self._ontology.is_modified and (self.class_cache or self._property_cache):
+            self.reset_and_disable_cache()
         property_cache = self._property_cache
 
         if property_cache:
@@ -1035,7 +902,7 @@ def _(self, ce: OWLDataSomeValuesFrom) -> FrozenSet[OWLNamedIndividual]:
                     ind |= {s}
             else:
                 for s in subs:
-                    for lit in self._base_reasoner.data_property_values(s, pe):
+                    for lit in self.data_property_values(s, pe):
                         if lit.get_datatype() == filler:
                             ind |= {s}
                             break
@@ -1047,7 +914,7 @@ def _(self, ce: OWLDataSomeValuesFrom) -> FrozenSet[OWLNamedIndividual]:
                         ind |= {s}
             else:
                 for s in subs:
-                    for lit in self._base_reasoner.data_property_values(s, pe):
+                    for lit in self.data_property_values(s, pe):
                         if lit in values:
                             ind |= {s}
                             break
@@ -1092,7 +959,7 @@ def include(lv: OWLLiteral):
                             break
             else:
                 for s in subs:
-                    for lit in self._base_reasoner.data_property_values(s, pe):
+                    for lit in self.data_property_values(s, pe):
                         if include(lit):
                             ind |= {s}
                             break
@@ -1123,9 +990,18 @@ def _(self, ce: OWLDataHasValue) -> FrozenSet[OWLNamedIndividual]:
     def _lazy_cache_class(self, c: OWLClass) -> None:
         if c in self._cls_to_ind:
             return
-        temp = self._base_reasoner.instances(c)
+        temp = self.get_instances_from_owl_class(c)
         self._cls_to_ind[c] = frozenset(temp)
 
+    def get_instances_from_owl_class(self, c: OWLClass):
+        if c.is_owl_thing():
+            yield from self._ontology.individuals_in_signature()
+        elif isinstance(c, OWLClass):
+            c_x: owlready2.ThingClass = self._world[c.str]
+            for i in c_x.instances(world=self._world):
+                if isinstance(i, owlready2.Thing):
+                    yield OWLNamedIndividual(IRI.create(i.iri))
+
     def _retrieve_triples(self, pe: OWLPropertyExpression) -> Iterable:
         """Retrieve all subject/object pairs for the given property."""
 
@@ -1148,8 +1024,13 @@ def _retrieve_triples(self, pe: OWLPropertyExpression) -> Iterable:
             relations = chain(relations, indirect_relations)
         yield from relations
 
+    def reset_and_disable_cache(self):
+        self.class_cache = False
+        self._property_cache = False
+        self.reset()
+
 
-class SyncReasoner(AbstractOWLReasonerEx):
+class SyncReasoner(AbstractOWLReasoner):
 
     def __init__(self, ontology: Union[SyncOntology, str], reasoner="HermiT"):
         """
diff --git a/owlapy/parser.py b/owlapy/parser.py
index 06bbcc9c..58a5b5e1 100644
--- a/owlapy/parser.py
+++ b/owlapy/parser.py
@@ -55,7 +55,7 @@
     data_union = data_intersection (must_ws "or" must_ws data_intersection)*
     data_intersection = data_primary (must_ws "and" must_ws data_primary)*
     datatype_restriction = datatype_iri "[" maybe_ws facet_restrictions maybe_ws "]"
-    facet_restrictions = facet_restriction (maybe_ws "," maybe_ws facet_restriction)*
+    facet_restrictions = facet_restriction (maybe_ws "⊓" maybe_ws facet_restriction)*
     facet_restriction = facet must_ws literal
     facet = "length" / "minLength" / "maxLength" / "pattern" / "langRange"
             / "totalDigits" / "fractionDigits" / "<=" / ">=" / "<" / ">"
@@ -454,7 +454,7 @@ def generic_visit(self, node, children):
     data_union = data_intersection (must_ws "⊔" must_ws data_intersection)*
     data_intersection = data_primary (must_ws "⊓" must_ws data_primary)*
     datatype_restriction = datatype_iri "[" maybe_ws facet_restrictions maybe_ws "]"
-    facet_restrictions = facet_restriction (maybe_ws "," maybe_ws facet_restriction)*
+    facet_restrictions = facet_restriction (maybe_ws "⊓" maybe_ws facet_restriction)*
     facet_restriction = facet must_ws literal
     facet = "length" / "minLength" / "maxLength" / "pattern" / "langRange"
             / "totalDigits" / "fractionDigits" / "≥" / "≤" / "<" / ">"
diff --git a/owlapy/render.py b/owlapy/render.py
index 62a1aa90..9856c5b7 100644
--- a/owlapy/render.py
+++ b/owlapy/render.py
@@ -269,7 +269,7 @@ def _(self, r: OWLFacetRestriction) -> str:
     @render.register
     def _(self, r: OWLDatatypeRestriction) -> str:
         s = [self.render(_) for _ in r.get_facet_restrictions()]
-        return "%s[%s]" % (self.render(r.get_datatype()), (" %s " % _DL_SYNTAX.COMMA).join(s))
+        return "%s[%s]" % (self.render(r.get_datatype()), (" %s " % _DL_SYNTAX.AND).join(s))
 
     @render.register
     def _(self, r: OWLDataHasValue):
@@ -463,7 +463,7 @@ def _(self, r: OWLFacetRestriction):
     @render.register
     def _(self, r: OWLDatatypeRestriction):
         s = [self.render(_) for _ in r.get_facet_restrictions()]
-        return "%s[%s]" % (self.render(r.get_datatype()), (" %s " % _MAN_SYNTAX.COMMA).join(s))
+        return "%s[%s]" % (self.render(r.get_datatype()), (" %s " % _MAN_SYNTAX.AND).join(s))
 
     @render.register
     def _(self, r: OWLDataHasValue):


Test patch:
diff --git a/tests/test_owlapy_conversions.py b/tests/test_owlapy_conversions.py
index ec927953..dae7373b 100644
--- a/tests/test_owlapy_conversions.py
+++ b/tests/test_owlapy_conversions.py
@@ -20,6 +20,8 @@
 from owlapy.providers import owl_datatype_max_exclusive_restriction, owl_datatype_min_exclusive_restriction, owl_datatype_min_max_exclusive_restriction, owl_datatype_min_max_inclusive_restriction
 
 from owlapy.vocab import OWLFacet
+
+
 class TestOWLConversions(unittest.TestCase):
     def test_owlapy_to_dl_str_and_back(self):
         NS = "http://example.com/father#"
@@ -75,7 +77,7 @@ def test_owlapy_to_dl_str_and_back(self):
         c = OWLDataAllValuesFrom(property=has_age, filler=OWLDataUnionOf([owl_datatype_min_max_inclusive_restriction(40, 80), IntegerOWLDatatype]))
         rendered_c = renderer.render(c)
         self.assertEqual(c, parser.parse_expression(rendered_c))
-        self.assertEqual(rendered_c, "∀ hasAge.(xsd:integer[≥ 40 , ≤ 80] ⊔ xsd:integer)")
+        self.assertEqual(rendered_c, "∀ hasAge.(xsd:integer[≥ 40 ⊓ ≤ 80] ⊔ xsd:integer)")
         # (9)
         c = OWLDataSomeValuesFrom(property=has_age,
                                    filler=OWLDataIntersectionOf([OWLDataOneOf([OWLLiteral(32.5), OWLLiteral(4.5)]),
@@ -246,7 +248,7 @@ def test_data_properties_numeric(self):
         self.assertEqual(p, c)
 
         p = self.parser.parse_expression('charge some <http://www.w3.org/2001/XMLSchema#double>'
-                                         '[> "4.4"^^xsd:double, < -32.5]')
+                                         '[> "4.4"^^xsd:double ⊓ < -32.5]')
         c = OWLDataSomeValuesFrom(self.charge, owl_datatype_min_max_exclusive_restriction(4.4, -32.5))
         self.assertEqual(p, c)
 
@@ -263,7 +265,7 @@ def test_data_properties_numeric(self):
         c = OWLDataMinCardinality(25, self.charge, filler)
         self.assertEqual(p, c)
 
-        p = self.parser.parse_expression('act exactly 11 xsd:integer[totalDigits "5"^^xsd:integer, > -100]')
+        p = self.parser.parse_expression('act exactly 11 xsd:integer[totalDigits "5"^^xsd:integer ⊓ > -100]')
         filler = OWLDatatypeRestriction(IntegerOWLDatatype, (OWLFacetRestriction(OWLFacet.TOTAL_DIGITS, 5),
                                                              OWLFacetRestriction(OWLFacet.MIN_EXCLUSIVE, -100)))
         c = OWLDataExactCardinality(11, self.act, filler)
@@ -303,14 +305,14 @@ def test_data_properties_string(self):
 
     def test_data_properties_time(self):
         p = self.parser.parse_expression('charge some <http://www.w3.org/2001/XMLSchema#date>'
-                                         '[> 2012-10-09, < "1990-01-31"^^xsd:date]')
+                                         '[> 2012-10-09 ⊓ < "1990-01-31"^^xsd:date]')
         filler = owl_datatype_min_max_exclusive_restriction(date(year=2012, month=10, day=9),
                                                             date(year=1990, month=1, day=31))
         c = OWLDataSomeValuesFrom(self.charge, filler)
         self.assertEqual(p, c)
 
         p = self.parser.parse_expression('charge exactly 10 dateTime'
-                                         '[> 2012-12-31T23:59:59Z, < 2000-01-01 01:01:01.999999]')
+                                         '[> 2012-12-31T23:59:59Z ⊓ < 2000-01-01 01:01:01.999999]')
         filler = owl_datatype_min_max_exclusive_restriction(datetime(year=2012, month=12, day=31, hour=23,
                                                                      minute=59, second=59, tzinfo=timezone.utc),
                                                             datetime(year=2000, month=1, day=1, hour=1, minute=1,
@@ -325,7 +327,7 @@ def test_data_properties_time(self):
         self.assertEqual(p, c)
 
         p = self.parser.parse_expression('charge only <http://www.w3.org/2001/XMLSchema#duration>'
-                                         '[> P10W20DT8H12M10S, < "P10M10.999999S"^^xsd:duration]')
+                                         '[> P10W20DT8H12M10S ⊓ < "P10M10.999999S"^^xsd:duration]')
         filler = owl_datatype_min_max_exclusive_restriction(Timedelta(weeks=10, days=20, hours=8, minutes=12, seconds=10),
                                                             Timedelta(minutes=10, seconds=10, microseconds=999999))
         c = OWLDataAllValuesFrom(self.charge, filler)
@@ -385,7 +387,7 @@ def test_whitespace(self):
         c = OWLDataAllValuesFrom(self.act, OWLDataOneOf((OWLLiteral(1.2), OWLLiteral(3.2))))
         self.assertEqual(p, c)
 
-        p = self.parser.parse_expression('act some (  xsd:double[  > 5f,< 4.2f \n, <  -1.8e10f  ]\t and  integer )')
+        p = self.parser.parse_expression('act some (  xsd:double[  > 5f ⊓ < 4.2f \n ⊓ <  -1.8e10f  ]\t and  integer )')
         f1 = OWLFacetRestriction(OWLFacet.MIN_EXCLUSIVE, OWLLiteral(5.0))
         f2 = OWLFacetRestriction(OWLFacet.MAX_EXCLUSIVE, OWLLiteral(4.2))
         f3 = OWLFacetRestriction(OWLFacet.MAX_EXCLUSIVE, OWLLiteral(-1.8e10))
@@ -506,7 +508,7 @@ def test_data_properties_numeric(self):
         self.assertEqual(p, c)
 
         p = self.parser.parse_expression('∃ charge.<http://www.w3.org/2001/XMLSchema#double>'
-                                         '[> "4.4"^^xsd:double, < -32.5]')
+                                         '[> "4.4"^^xsd:double ⊓ < -32.5]')
         c = OWLDataSomeValuesFrom(self.charge, owl_datatype_min_max_exclusive_restriction(4.4, -32.5))
         self.assertEqual(p, c)
 
@@ -523,7 +525,7 @@ def test_data_properties_numeric(self):
         c = OWLDataMaxCardinality(25, self.charge, filler)
         self.assertEqual(p, c)
 
-        p = self.parser.parse_expression('= 11 act.xsd:integer[totalDigits "5"^^xsd:integer, > -100]')
+        p = self.parser.parse_expression('= 11 act.xsd:integer[totalDigits "5"^^xsd:integer ⊓ > -100]')
         filler = OWLDatatypeRestriction(IntegerOWLDatatype, (OWLFacetRestriction(OWLFacet.TOTAL_DIGITS, 5),
                                                              OWLFacetRestriction(OWLFacet.MIN_EXCLUSIVE, -100)))
         c = OWLDataExactCardinality(11, self.act, filler)
@@ -563,14 +565,14 @@ def test_data_properties_string(self):
 
     def test_data_properties_time(self):
         p = self.parser.parse_expression('∃ charge.<http://www.w3.org/2001/XMLSchema#date>'
-                                         '[> 2012-10-09, < "1990-01-31"^^xsd:date]')
+                                         '[> 2012-10-09 ⊓ < "1990-01-31"^^xsd:date]')
         filler = owl_datatype_min_max_exclusive_restriction(date(year=2012, month=10, day=9),
                                                             date(year=1990, month=1, day=31))
         c = OWLDataSomeValuesFrom(self.charge, filler)
         self.assertEqual(p, c)
 
         p = self.parser.parse_expression('= 10 charge.dateTime'
-                                         '[> 2012-12-31T23:59:59Z, < 2000-01-01 01:01:01.999999]')
+                                         '[> 2012-12-31T23:59:59Z ⊓ < 2000-01-01 01:01:01.999999]')
         filler = owl_datatype_min_max_exclusive_restriction(datetime(year=2012, month=12, day=31, hour=23,
                                                                      minute=59, second=59, tzinfo=timezone.utc),
                                                             datetime(year=2000, month=1, day=1, hour=1, minute=1,
@@ -585,7 +587,7 @@ def test_data_properties_time(self):
         self.assertEqual(p, c)
 
         p = self.parser.parse_expression('∀ charge.<http://www.w3.org/2001/XMLSchema#duration>'
-                                         '[> P10W20DT8H12M10S, < "P10M10.999999S"^^xsd:duration]')
+                                         '[> P10W20DT8H12M10S ⊓ < "P10M10.999999S"^^xsd:duration]')
         filler = owl_datatype_min_max_exclusive_restriction(Timedelta(weeks=10, days=20, hours=8, minutes=12, seconds=10),
                                                             Timedelta(minutes=10, seconds=10, microseconds=999999))
         c = OWLDataAllValuesFrom(self.charge, filler)
@@ -645,7 +647,7 @@ def test_whitespace(self):
         c = OWLDataAllValuesFrom(self.act, OWLDataOneOf((OWLLiteral(1.2), OWLLiteral(3.2))))
         self.assertEqual(p, c)
 
-        p = self.parser.parse_expression('∃ act.(  xsd:double[  > 5f,< 4.2f \n, <  -1.8e10f  ]\t ⊓  integer )')
+        p = self.parser.parse_expression('∃ act.(  xsd:double[  > 5f ⊓ < 4.2f \n ⊓ <  -1.8e10f  ]\t ⊓  integer )')
         f1 = OWLFacetRestriction(OWLFacet.MIN_EXCLUSIVE, OWLLiteral(5.0))
         f2 = OWLFacetRestriction(OWLFacet.MAX_EXCLUSIVE, OWLLiteral(4.2))
         f3 = OWLFacetRestriction(OWLFacet.MAX_EXCLUSIVE, OWLLiteral(-1.8e10))
@@ -703,7 +705,7 @@ def test_ce_render(self):
 
         dr = OWLDataAllValuesFrom(property=has_age, filler=OWLDataUnionOf([datatype_restriction, IntegerOWLDatatype]))
         r = renderer.render(dr)
-        self.assertEqual(r, "∀ hasAge.(xsd:integer[≥ 40 , ≤ 80] ⊔ xsd:integer)")
+        self.assertEqual(r, "∀ hasAge.(xsd:integer[≥ 40 ⊓ ≤ 80] ⊔ xsd:integer)")
 
         dr = OWLDataSomeValuesFrom(property=has_age,
                                    filler=OWLDataIntersectionOf([OWLDataOneOf([OWLLiteral(32.5), OWLLiteral(4.5)]),
@@ -776,7 +778,7 @@ def test_ce_render(self):
 
         dr = OWLDataAllValuesFrom(property=has_age, filler=OWLDataUnionOf([datatype_restriction, IntegerOWLDatatype]))
         r = renderer.render(dr)
-        self.assertEqual(r, "hasAge only (xsd:integer[>= 40 , <= 80] or xsd:integer)")
+        self.assertEqual(r, "hasAge only (xsd:integer[>= 40 and <= 80] or xsd:integer)")
 
         dr = OWLDataSomeValuesFrom(property=has_age,
                                    filler=OWLDataIntersectionOf([OWLDataOneOf([OWLLiteral(32.5), OWLLiteral(4.5)]),
diff --git a/tests/test_owlapy_ontology_management.py b/tests/test_owlapy_ontology_management.py
index 96a3ed9f..cf8d4644 100644
--- a/tests/test_owlapy_ontology_management.py
+++ b/tests/test_owlapy_ontology_management.py
@@ -2,7 +2,7 @@
 import unittest
 
 from pandas import Timedelta
-from owlapy.owl_reasoner import FastInstanceCheckerReasoner, OntologyReasoner, SyncReasoner
+from owlapy.owl_reasoner import StructuralReasoner, SyncReasoner
 from owlapy.providers import owl_datatype_max_inclusive_restriction, owl_datatype_min_inclusive_restriction, \
                               owl_datatype_min_max_exclusive_restriction, owl_datatype_min_max_inclusive_restriction
 
@@ -36,7 +36,7 @@ def test_equivalent_classes(self):
         ns = "http://dl-learner.org/mutagenesis#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Mutagenesis/mutagenesis.owl"))
-        reasoner = OntologyReasoner(onto)
+        reasoner = StructuralReasoner(onto)
 
         atom = OWLClass(IRI(ns, 'Atom'))
         bond = OWLClass(IRI(ns, 'Bond'))
@@ -80,7 +80,7 @@ def test_sub_classes(self):
         ns = "http://dl-learner.org/mutagenesis#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Mutagenesis/mutagenesis.owl"))
-        reasoner = OntologyReasoner(onto)
+        reasoner = StructuralReasoner(onto)
 
         bond = OWLClass(IRI(ns, 'Bond'))
         ball3 = OWLClass(IRI(ns, 'Ball3'))
@@ -141,7 +141,7 @@ def test_super_classes(self):
         ns = "http://dl-learner.org/mutagenesis#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Mutagenesis/mutagenesis.owl"))
-        reasoner = OntologyReasoner(onto)
+        reasoner = StructuralReasoner(onto)
 
         bond = OWLClass(IRI(ns, 'Bond'))
         ball3 = OWLClass(IRI(ns, 'Ball3'))
@@ -203,7 +203,7 @@ def test_sub_object_properties(self):
         ns = "http://www.biopax.org/examples/glycolysis#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Biopax/biopax.owl"))
-        reasoner = OntologyReasoner(onto)
+        reasoner = StructuralReasoner(onto)
 
         participants = OWLObjectProperty(IRI.create(ns, 'PARTICIPANTS'))
         target_props = frozenset({OWLObjectProperty(IRI(ns, 'COFACTOR')),
@@ -218,7 +218,7 @@ def test_instances(self):
         ns = "http://example.com/father#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Family/father.owl"))
-        reasoner = OntologyReasoner(onto)
+        reasoner = StructuralReasoner(onto)
 
         inst = frozenset(reasoner.instances(OWLThing))
         target_inst = frozenset({OWLNamedIndividual(IRI(ns, 'anna')),
@@ -238,7 +238,7 @@ def test_types(self):
         ns = "http://example.com/father#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Family/father.owl"))
-        reasoner = OntologyReasoner(onto)
+        reasoner = StructuralReasoner(onto)
 
         types = frozenset(reasoner.types(OWLNamedIndividual(IRI.create(ns, 'stefan'))))
         target_types = frozenset({OWLThing, OWLClass(IRI(ns, 'male')), OWLClass(IRI(ns, 'person'))})
@@ -248,7 +248,7 @@ def test_object_values(self):
         ns = "http://example.com/father#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Family/father.owl"))
-        reasoner = OntologyReasoner(onto)
+        reasoner = StructuralReasoner(onto)
 
         stefan = OWLNamedIndividual(IRI.create(ns, 'stefan'))
         markus = OWLNamedIndividual(IRI.create(ns, 'markus'))
@@ -308,8 +308,7 @@ def test_data_values(self):
         ns = "http://dl-learner.org/mutagenesis#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Mutagenesis/mutagenesis.owl"))
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner)
+        reasoner = StructuralReasoner(onto)
 
         d100_1 = OWLNamedIndividual(IRI.create(ns, 'd100_1'))
         charge = OWLDataProperty(IRI.create(ns, 'charge'))
@@ -338,8 +337,7 @@ def test_all_data_values(self):
         ns = "http://dl-learner.org/mutagenesis#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Mutagenesis/mutagenesis.owl"))
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner)
+        reasoner = StructuralReasoner(onto)
 
         charge = OWLDataProperty(IRI.create(ns, 'charge'))
         super_charge = OWLDataProperty(IRI.create(ns, 'super_charge'))
@@ -359,8 +357,7 @@ def test_ind_object_properties(self):
         ns = "http://example.com/father#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Family/father.owl"))
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner)
+        reasoner = StructuralReasoner(onto)
 
         stefan = OWLNamedIndividual(IRI.create(ns, 'stefan'))
         has_child = OWLObjectProperty(IRI.create(ns, 'hasChild'))
@@ -380,8 +377,7 @@ def test_ind_data_properties(self):
         ns = "http://dl-learner.org/mutagenesis#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Mutagenesis/mutagenesis.owl"))
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner)
+        reasoner = StructuralReasoner(onto)
 
         d100_1 = OWLNamedIndividual(IRI.create(ns, 'd100_1'))
         charge = OWLDataProperty(IRI.create(ns, 'charge'))
@@ -401,7 +397,7 @@ def test_add_remove_axiom(self):
         ns = "http://example.com/father#"
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create("file://KGs/Family/father.owl"))
-        reasoner = OntologyReasoner(onto)
+        reasoner = StructuralReasoner(onto)
 
         markus = OWLNamedIndividual(IRI.create(ns, 'markus'))
         michelle = OWLNamedIndividual(IRI.create(ns, 'michelle'))
diff --git a/tests/test_owlapy_owl2sparql_converter.py b/tests/test_owlapy_owl2sparql_converter.py
index 477e3769..c7a702d3 100644
--- a/tests/test_owlapy_owl2sparql_converter.py
+++ b/tests/test_owlapy_owl2sparql_converter.py
@@ -5,7 +5,7 @@
 from owlapy.iri import IRI
 from owlapy.owl_property import OWLObjectProperty
 from owlapy.owl_ontology_manager import OntologyManager
-from owlapy.owl_reasoner import OntologyReasoner, FastInstanceCheckerReasoner
+from owlapy.owl_reasoner import StructuralReasoner
 from owlapy.parser import DLSyntaxParser
 from rdflib import Graph
 from owlapy.converter import Owl2SparqlConverter
@@ -95,8 +95,7 @@ def test_Single(self):
         # knowledge base - using OWLReasoner
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create(PATH_FAMILY))
-        base_reasoner = OntologyReasoner(onto)
-        family_kb_reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
+        family_kb_reasoner = StructuralReasoner(onto, negation_default=True)
 
         ce_str = "Brother"
         ce_parsed = DLSyntaxParser(namespace="http://www.benchmark.org/family#").parse_expression(expression_str=ce_str)
@@ -139,8 +138,7 @@ def test_Intersection(self):
         # knowledge base - using OWLReasoner
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create(PATH_FAMILY))
-        base_reasoner = OntologyReasoner(onto)
-        family_kb_reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
+        family_kb_reasoner = StructuralReasoner(onto, negation_default=True)
 
         ce_str = "Brother ⊓ Father"
         ce_parsed = DLSyntaxParser(namespace="http://www.benchmark.org/family#").parse_expression(expression_str=ce_str)
@@ -167,8 +165,7 @@ def test_Union(self):
         # knowledge base - using OWLReasoner
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create(PATH_FAMILY))
-        base_reasoner = OntologyReasoner(onto)
-        family_kb_reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
+        family_kb_reasoner = StructuralReasoner(onto, negation_default=True)
 
         ce_str = "Sister ⊔ Mother"
         ce_parsed = DLSyntaxParser(namespace="http://www.benchmark.org/family#").parse_expression(expression_str=ce_str)
@@ -196,8 +193,7 @@ def test_Complement(self):
         # knowledge base - using OWLReasoner
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create(PATH_FAMILY))
-        base_reasoner = OntologyReasoner(onto)
-        family_kb_reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
+        family_kb_reasoner = StructuralReasoner(onto, negation_default=True)
 
         ce_str = "¬Mother"
         ce_parsed = DLSyntaxParser(namespace="http://www.benchmark.org/family#").parse_expression(expression_str=ce_str)
@@ -225,8 +221,7 @@ def test_Exists(self):
         # knowledge base - using OWLReasoner
         mgr = OntologyManager()
         onto = mgr.load_ontology(IRI.create(PATH_FAMILY))
-        base_reasoner = OntologyReasoner(onto)
-        family_kb_reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
+        family_kb_reasoner = StructuralReasoner(onto, negation_default=True)
 
         ce_str = "∃hasChild.Male"
         ce_parsed = DLSyntaxParser(namespace="http://www.benchmark.org/family#").parse_expression(expression_str=ce_str)
diff --git a/tests/test_owlapy_fastinstancechecker.py b/tests/test_owlapy_structural_reasoner.py
similarity index 91%
rename from tests/test_owlapy_fastinstancechecker.py
rename to tests/test_owlapy_structural_reasoner.py
index ea0e061b..b9c08b30 100644
--- a/tests/test_owlapy_fastinstancechecker.py
+++ b/tests/test_owlapy_structural_reasoner.py
@@ -14,13 +14,13 @@
 from owlapy.owl_property import OWLObjectInverseOf, OWLObjectProperty, OWLDataProperty
 from owlready2.prop import DataProperty
 
-from owlapy.owl_reasoner import FastInstanceCheckerReasoner, OntologyReasoner
+from owlapy.owl_reasoner import StructuralReasoner
 
 from owlapy.providers import owl_datatype_min_max_inclusive_restriction, owl_datatype_min_max_exclusive_restriction, \
                              owl_datatype_max_inclusive_restriction
 
 
-class Owlapy_FastInstanceChecker_Test(unittest.TestCase):
+class Owlapy_StructuralReasoner_Test(unittest.TestCase):
     # noinspection DuplicatedCode
     def test_instances(self):
         NS = "http://example.com/father#"
@@ -31,8 +31,7 @@ def test_instances(self):
         female = OWLClass(IRI.create(NS, 'female'))
         has_child = OWLObjectProperty(IRI(NS, 'hasChild'))
 
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner)
+        reasoner = StructuralReasoner(onto)
 
         self.assertEqual([], list(reasoner.sub_object_properties(has_child, direct=True)))
 
@@ -82,9 +81,8 @@ def test_complement(self):
         female = OWLClass(IRI.create(NS, 'female'))
         has_child = OWLObjectProperty(IRI(NS, 'hasChild'))
 
-        base_reasoner = OntologyReasoner(onto)
-        reasoner_nd = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
-        reasoner_open = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=False)
+        reasoner_nd = StructuralReasoner(onto, negation_default=True)
+        reasoner_open = StructuralReasoner(onto, negation_default=False)
 
         self.assertEqual(set(reasoner_nd.instances(male)), set(reasoner_nd.instances(OWLObjectComplementOf(female))))
         self.assertEqual(set(reasoner_nd.instances(female)), set(reasoner_nd.instances(OWLObjectComplementOf(male))))
@@ -108,8 +106,7 @@ def test_all_values(self):
 
         has_child = OWLObjectProperty(IRI(NS, 'hasChild'))
 
-        base_reasoner = OntologyReasoner(onto)
-        reasoner_nd = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
+        reasoner_nd = StructuralReasoner(onto, negation_default=True)
 
         # note, these answers are all wrong under OWA
         no_child = frozenset(reasoner_nd.instances(OWLObjectAllValuesFrom(property=has_child, filler=OWLNothing)))
@@ -125,8 +122,7 @@ def test_complement2(self):
         male = OWLClass(IRI.create(NS, 'male'))
         female = OWLClass(IRI.create(NS, 'female'))
 
-        base_reasoner = OntologyReasoner(onto)
-        reasoner_open = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=False)
+        reasoner_open = StructuralReasoner(onto, negation_default=False)
 
         # Should be empty under open world assumption
         self.assertEqual(set(), set(reasoner_open.instances(OWLObjectComplementOf(female))))
@@ -141,8 +137,7 @@ def test_cardinality_restrictions(self):
         atom = OWLClass(IRI.create(NS, 'Atom'))
         has_atom = OWLObjectProperty(IRI(NS, 'hasAtom'))
 
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
+        reasoner = StructuralReasoner(onto, negation_default=True)
 
         inst = frozenset(reasoner.instances(OWLObjectExactCardinality(cardinality=2,
                                                                       property=has_atom,
@@ -178,8 +173,7 @@ def test_data_properties(self):
         logp = OWLDataProperty(IRI(NS, 'logp'))
         charge = OWLDataProperty(IRI(NS, 'charge'))
 
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, negation_default=True)
+        reasoner = StructuralReasoner(onto, negation_default=True)
 
         self.assertEqual([], list(reasoner.sub_data_properties(act, direct=True)))
 
@@ -274,8 +268,7 @@ class birthDateTime(DataProperty):
         michelle = OWLNamedIndividual(IRI(NS, 'michelle'))
         martin = OWLNamedIndividual(IRI(NS, 'martin'))
 
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner)
+        reasoner = StructuralReasoner(onto)
 
         restriction = owl_datatype_min_max_exclusive_restriction(date(year=1995, month=6, day=12),
                                                             date(year=1999, month=3, day=2))
@@ -312,8 +305,13 @@ def test_sub_property_inclusion(self):
         onto.add_axiom(OWLSubDataPropertyOfAxiom(charge, super_charge))
 
         # sub_property = True
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, sub_properties=True)
+        reasoner = StructuralReasoner(onto, sub_properties=True)
+        reasoner._ontology.is_modified = False  # This is done because, for sub_properties to work as expected it needs
+                                                # _property_cache of the reasoner to be True which would normally be
+                                                # False when the ontology is modified. Info: Cache needs to be reset and
+                                                # disabled when ontolgy modification is detected because the
+                                                # cached facts may not hold anymore. Hence, setting is_modified to False
+                                                # is an excepton to check this test.
 
         # object property
         ce = OWLObjectIntersectionOf([compound, OWLObjectSomeValuesFrom(super_has_structure, benzene)])
@@ -326,8 +324,7 @@ def test_sub_property_inclusion(self):
         self.assertEqual(len(individuals), 75)
 
         # sub_property = False
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, sub_properties=False)
+        reasoner = StructuralReasoner(onto, sub_properties=False)
 
         # object property
         ce = OWLObjectIntersectionOf([compound, OWLObjectSomeValuesFrom(super_has_structure, benzene)])
@@ -356,8 +353,7 @@ def test_inverse(self):
                    OWLNamedIndividual(IRI.create(ns, 'stefan')),
                    OWLNamedIndividual(IRI.create(ns, 'markus'))}
 
-        base_reasoner = OntologyReasoner(onto)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, sub_properties=False)
+        reasoner = StructuralReasoner(onto, sub_properties=False)
 
         expr = OWLObjectSomeValuesFrom(has_child, OWLThing)
         expr_inverse = OWLObjectSomeValuesFrom(OWLObjectInverseOf(has_child_inverse), OWLThing)
@@ -383,7 +379,7 @@ def test_inverse(self):
         self.assertEqual(parents_expr_inverse, frozenset())
 
         # True (sub properties taken into account)
-        reasoner = FastInstanceCheckerReasoner(onto, base_reasoner=base_reasoner, sub_properties=True)
+        reasoner = StructuralReasoner(onto,  sub_properties=True)
         expr = OWLObjectSomeValuesFrom(super_has_child, OWLThing)
         expr_inverse = OWLObjectSomeValuesFrom(OWLObjectInverseOf(super_has_child_inverse), OWLThing)
         parents_expr = frozenset(reasoner.instances(expr))