compared with
Current by Vladimir Alexiev
on Dec 09, 2013 15:58.

Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (84)

View Page History
{toc}
{color:red}*Do not edit this page in Rich Text mode, edit only in Wiki mode*{color}
This page's source is in SVN: [https://svn.ontotext.com/svn/researchspace/trunk/search/FR-Implementation.txt].
So you may comment, but I'll edit the SVN version, taking your comment into account

{toc}

h1. Introduction


h2. FR Dependency Graph
FR-weave.pl also generates a dependency graph (processed with graphviz dot) showing which CRM props and sub-FRs are used in the implementation of each FR. Legend:
- This lets you see which CRM properties are "bundled" into which FRs. Similar info about the old implementation is at [FR Implementation-old#FR Summary (Short Variant)] or [FR Implementation-old#FR Summary (Long Variant)]
- It was an indispensable debugging aid while creating th FRs.
- plain text: 51 source classes/properties
- filled rectangles: 13 intermediate sub-FRs
- rectangles: 19 target FRs

FR-graph.gv is processed with graphviz dot to create [^FR-graph.png]:
This lets you see which CRM properties are "bundled" into which FRs.
- It was an indispensable debugging aid while creating th FRs (that there are no disconnected properties, each FR uses all source properties as expected, etc).
- Similar info about the old implementation is at [FR Implementation-old#FR Summary (Short Variant)] or [FR Implementation-old#FR Summary (Long Variant)]

[^FR-graph.png] (full resolution)
!FR-graph.png|width=1000!

h2. Prefixes
This adds prefixes to FR.ttl:
This would add prefixes to FR.ttl (but we don't use such file):
{code:title=Turtle}
@prefix crm : <http://erlangen-crm.org/current/> .
{code:title=Prefices}
crm : http://erlangen-crm.org/current/
ptop: http://www.ontotext.com/proton/protontop#
bmo : http://collection.britishmuseum.org/id/ontology/
rso : http://www.researchspace.org/ontology/

h2. Transitive Properties
ECRM declares appropriate CRM properties as owl:TransitiveProperty.
For some reason it doesn't declare P9,P46 transitive, though it does it for other "part of" properties, eg P106,P148. I posted a bug to CRM SIG and fix it here:

h3. TransitiveProperty
owl:TransitiveProperty is a well-known OWL type stating that a property is transitive. ECRM declares the appropriate CRM properties as transitive, but for some reason it doesn't declare P9,P46 transitive (other "part of" properties, eg P106,P148 are transitive). I posted a bug to CRM SIG and fix it here:
{code:title=Axioms}
<crm:P9_consists_of> <rdf:type> <owl:TransitiveProperty>
- P148_has_component, P148i_is_component_of

Note: we used to use owl:TransitiveProperty to make the transitive closure for some properties. sub-FRs. But now we prefer to do it with explicit rules, since we want to always start at FC70_Thing, so as to eliminate useless triples

h2. Inverse Properties
Most CRM properties have an inverse, eg P110i_was_augmented_by is inverse of P110_augmented (Symmetric properties are their own inverse). ECRM declares all inverse properties as owl:inverseOf.
h3. transitiveOver
ptop:transitiveOver is a useful generalization defined by the [Proton Ontology|http://www.ontotext.com/proton-ontology]. The semantics is defined with the following axiom:
{noformat}(p,transitiveOver,q) (x,p,y) (y,q,z) => (x,p,z){noformat}
Sample usage is:
{noformat}(locatedIn, transitiveOver, subRegionOf) (Ontotext,locatedIn,Bulgaria) (Bulgaria,subRegionOf,Europe) => (Ontotext,locatedIn,Europe){noformat}

We use this in FR-Transitive.ttl (described in [FR Transitivity]) to state that certain FRs are transitive over skos:broader.

We use the RDFS reasoning dialect as a basis, which implements rdfs:subClassOf and rdfs:subPropertyOf reasoning. To this we add relevant rules from builtin_owl2-rl.pie:
But it's very useful in FR definitions to rely on general Transitive and Inverse reasoning, which frees you from dependencies on how exactly data is asserted.
So we copy the relevant rules from builtin_owl2-rl.pie:
{code:title=Rules}
p <ptop:transitiveOver> q; x p y; y q z => x p z
p <rdf:type> <owl:TransitiveProperty>; x p y; y p z => x p z
{code}

TODO: ptop:transitiveOver is more efficient than owl:TransitiveProperty since it uses only the step relation (eg skos:broader) but not its transitive closure (eg skos:broaderTransitive). Unfortunately CRM doesn't define step relations for its transitive properties.

h2. Inverse Properties
Most CRM properties have an inverse, eg P110i_was_augmented_by is inverse of P110_augmented (Symmetric properties are their own inverse). ECRM declares all inverse properties as owl:inverseOf. Inverse reasoning is useful since it frees you from dependencies on how exactly the data is asserted:

{code:title=Rules}
p <owl:inverseOf> q; x p y => y q x
p <owl:inverseOf> q; x q y => y p x
{code}

h3. FC70_Thing and FR_dataset for RS
In RS we compute a dataset, which is important to select the right RForm; and to display a Dataset facet in the RS search. We now have 3 datasets (RKD, BM, YCBA):
- RKD data includes sub-objects (eg related/n is a related work, part/n is a frame that is part of a painting) that we can't display, so we introduced an extension sub-class rso:E22_Museum_Object. Because Rembrandt paintings come from different places, RKD data has varying keepers/owners: Mauritshuis, Rijksmuseum, Metropolitan, NGA.
- BM data uses crm:E22_Man-Made_Object. One of the current keepers is always the BM. The current owner may be missing (see [BM Association Mapping Problems#Poor Acquisition]), so we need to check both P52 and P50
- YCBA data uses crm:E22_Man-Made_Object, and the keeper/owner is YCBA.

In RS we search only for Man-Made Objects so the rule is simpler.
- RKD data includes sub-objects (eg related/n is a related work, part/n is a frame that is part of a painting) that we can't display, so we introduced an extension sub-class rso:E22_Museum_Object
- BM data uses crm:E22_Man-Made_Object, and we use an additional criterion "the current keeper or owner is the BM". (Objects which have been loaned to the BM have a different owner)
The BM has two sameAs URIs
- http://collection.britishmuseum.org/id/the-british-museum
- http://collection.britishmuseum.org/id/person-institution/104636

So to avoid duplicate results, we define the dataset as a literal.
Then FC70_Thing is defined as something with a dataset.

{code:title=Rules}
x <rdf:type> <rso:E22_Museum_Object> => x <rdf:type> <rso:FC70_Thing> <rso:FR_dataset> "RKD"
x <rdf:type> <crm:E22_Man-Made_Object>; x <crm:P50_has_current_keeper> <http://collection.britishmuseum.org/id/the-british-museum> => x <rdf:type> <rso:FC70_Thing> <rso:FR_dataset> "BM"
x <rdf:type> <crm:E22_Man-Made_Object>; x <crm:P52_has_current_owner> <http://collection.britishmuseum.org/id/the-british-museum> => x <rdf:type> <rso:FC70_Thing> <rso:FR_dataset> "BM"
x <rdf:type> <crm:E22_Man-Made_Object>; x <crm:P50_has_current_keeper> <http://vocab.getty.edu/ulan/500303557> => x <rso:FR_dataset> "YCBA"
x <rdf:type> <crm:E22_Man-Made_Object>; x <crm:P52_has_current_owner> <http://vocab.getty.edu/ulan/500303557> => x <rso:FR_dataset> "YCBA"
x <rso:FR_dataset> y => x <rdf:type> <rso:FC70_Thing>
{code}
Note: the Yale URI changed to a true ULAN URI, see [Yale Mapping Problems#Getty URIs]

h1. Fundamental Relations
{code:title=Rules}
x <rso:FRT_46_106_148> y => x <rso:FRT_46_106_148_128> y
x <rso:FRT_46_106_148_128> y; y <rso:FRT_46_106_148> z => x <rso:FRT_46_106_148_128> z
x <rdf:type> <rso:FC70_Thing>; x <crm:P128_carries> z => x <rso:FRT_46_106_148_128> z
x <rso:FRT_46_106_148_128> y; y <crm:P128_carries> z => x <rso:FRT_46_106_148_128> z
{code:title=Rules}
x <rso:FRT_46_106_148_128> y => x <rso:FRT_46_106_148_128_130> y
x <rso:FRT_46_106_148_128_130> y; y <rso:FRT_46_106_148_128> z => x <rso:FRT_46_106_148_128_130> z
x <rdf:type> <rso:FC70_Thing>; x <crm:P130_shows_features_of> y => x <rso:FRT_46_106_148_128_130> y
x <rdf:type> <rso:FC70_Thing>; x <crm:P130i_features_are_also_found_on> y => x <rso:FRT_46_106_148_128_130> y
{code}

- FRT9i_10 := (P9i_forms_part_of | P10_falls_within)+
- FRT9_10 := (P9_consists_of | P10_falls_within)+
{code:title=Rules}
x <crm:P9i_forms_part_of> y => x <rso:FRT9i_10> y
x <crm:P9_consists_of> y => x <rso:FRT9_10> y
x <crm:P10_falls_within> y => x <rso:FRT9i_10> y
x <rso:FRT9i_10> y; y <crm:P9i_forms_part_of> z => x <rso:FRT9i_10> z
x <rso:FRT9_10> y; y <crm:P9_consists_of> z => x <rso:FRT9_10> z
x <rso:FRT9i_10> y; y <crm:P10_falls_within> z => x <rso:FRT9i_10> z
{code}

{code}

- FRX24i_25i_30i := (FC70_Thing) (FRX24i_30i | P25i_moved_by) / P9_consists_of*
{code:title=Rules}
x <rso:FRX24i_30i> y => x <rso:FRX24i_25i_30i> y
x <rdf:type> <rso:FC70_Thing>; x <crm:P25i_moved_by> y => x <rso:FRX24i_25i_30i> y
x <rso:FRX24i_25i_30i> y; y <crm:P9_consists_of> z => x <rso:FRX24i_25i_30i> z
{code}

# We use the previously defined FRs "created in", "found at"
# Added E10_Transfer_of_Custody in addition to E8_Acquisition
# Loop P9_consists_of for E8_Acquisition
# Don't loop at the beginning since there's no info about separate Move/Acquisition/Custody of a part
# P26,P27 are subproperties of P7, so we don't need to use them
- instead of a generic P92i_was_brought_into_existence_by, we want these specific paths:
-- produced by: P108i_was_produced_by
-- produced by subevent: P108i_was_produced_by/P9_consists_of
We loop over the event hierarchy downwards since that's how BM data is laid out:
{noformat}
<object/RFM1664> P108i_was_produced_by <object/RFM1664/production>.
<object/RFM1664/production> P9_consists_of <object/RFM1664/production/1>.
<object/RFM1664/production/1> P14_carried_out_by <person>.
{noformat}
-- modified (repaired) by: P31i_was_modified_by (subsumes P108i_was_produced_by)
-- part made by: P46_is_composed_of/P108i_was_produced_by
-- inscription by: P65_shows_visual_item/P94i_was_created_by (subsumed by P128_carries)
- in addition to P46_is_composed_of for physical, we add P106_is_composed_of and P148_has_component for conceptual
- no point looping over event hierarchy (P9i_forms_part_of) since there is no such data

Implementation:
- FRX92i_created := (FC70_Thing) FRT_46_106_148_128* / (P31i_was_modified_by | P94i_was_created_by) / P9*
{code:title=Rules}
x <rdf:type> <rso:FC70_Thing>; x <crm:P31i_was_modified_by> y => x <rso:FRX92i_created> y
x <rdf:type> <rso:FC70_Thing>; x <crm:P94i_was_created_by> y => x <rso:FRX92i_created> y
x <rso:FRT_46_106_148_128> y; y <crm:P31i_was_modified_by> z => x <rso:FRX92i_created> z
x <rso:FRT_46_106_148_128> y; y <crm:P94i_was_created_by> z => x <rso:FRX92i_created> z
x <rso:FRX92i_created> y; y <crm:P9_consists_of> z => x <rso:FRX92i_created> z
{code}

- FR92i_created_by := FRX92i_created / P14_carried_out_by / P107i_is_current_or_former_member_of*
{code:title=Rules}
h3. Thing influenced-motivated by Actor- FR15_influenced_by
Thing's production was influenced/motivated by Actor (or group it is member of).
- Examples of [Influenced|BM Association Mapping#Influenced By] include Manner/School/Style of, After, Close to, Connected with.
- Examples of [Motivated|BM Association Mapping#Production Motivated By] include Eponym/ Governor/ Issuer/ Ruler/ Magistrate Eponym/Governor/Issuer/Ruler/Magistrate who authorised/ patronised/ ordered authorised/patronised/ordered the production; Made for.

We usere the same beginning as [#Thing created by Actor- FR92i_created_by]:
!FR15_influenced_by.png!

Implementation: P15_was_influenced_by subsumes P17_was_motivated_by.
{code:title=Rules}
x <crm:P108i_was_produced_by> <rso:FRX92i_created> y; y <crm:P15_was_influenced_by> z => x <rso:FR15_influenced_by> z
{code}

Fixed Problems:
# At beginning: we loop *down* the part hierarchy, for both physical and conceptual (P12 is applicable to any E77_Persistent_Item)
# We loop *down* the event hierarchy (P9_consists_of) since that's how BM data is laid out
# Curiously, CRM considers that a thing is *not* present at its E8_Acquisition or E10_Transfer_of_Custody: P24i_changed_ownership_through and P30i_custody_transferred_through are not subprops of P12i_was_present_at. Although physically possible, we have found that is surprising and confusing, so we add it.

Implementation:
- FR12_has_met := (P12i_was_present_at | FRX24i_25i_30i) / P12_occurred_in_the_presence_of (E39_Actor)
- FR12X := (FC70_Thing) FRT_46_106_148* / P12i_was_present_at / P9_consists_of*
{code:title=Rules}
x <crm:P12i_was_present_at> y; y <crm:P12_occurred_in_the_presence_of> z; z <rdf:type> <crm:E39_Actor> => x <rso:FR12_has_met> z
x <rso:FRX24i_25i_30i> y; y <crm:P12_occurred_in_the_presence_of> z; z <rdf:type> <crm:E39_Actor> => x <rso:FR12_has_met> z
y <rdf:type> <rso:FC70_Thing>; y <crm:P12i_was_present_at> z => y <rso:FR12X> z
x <rso:FRT_46_106_148> y; y <crm:P12i_was_present_at> z => x <rso:FR12X> z
x <rso:FR12X> y; y <crm:P9_consists_of> z => x <rso:FR12X> z
{code}
- FR12_has_met := FR12X / P12_occurred_in_the_presence_of (E39_Actor) |
FR51_former_or_current_owner_keeper
{code:title=Rules}
x <rso:FR12X> z; z <crm:P12_occurred_in_the_presence_of> t; t <rdf:type> <crm:E39_Actor> => x <rso:FR12_has_met> t
x <rso:FR51_former_or_current_owner_keeper> y => x <rso:FR12_has_met> y
{code}

h3. Thing is referred to by Actor- WONTDO
Fixed Problems:
# Allowed Period, which is a super-class of Event
# At end: don't navigate the event hierarchy (P9i_forms_part_of nor P10_falls_within)
# At end: don't navigate the event hierarchy (aboutness is neither covariant, nor contravariant)

Implementation: similar to other "About" properties so we reuse FRX67_about.
{section}{column}
As defined in FRThing.docx:
- FRThing.docx refers and FORTH TR-429 (p.59) refer to this variously as "has met" or "from"
!FR12_was_present_at.png!
{column}{column}
Corrected definition:
- we use FR12_has_met name "has_met" for Actor, so we use FR12_was_present_at name "was_present_at" for this. The name is derived from the name of the key constituent CRM property.
- we loop down the part hierarchy in the beginning to avoid [#BUG]
- loop at the beginning: traverse the part hierarchy downwards to avoid [#BUG]
- loop at the end: traverse the event hierarchy downwards (P9) and add P10: see [#Navigating the Event Hierarchy]
!FR12_was_present_at_fixed.png!
{column}{section}

Implementation
- FR12_was_present_at := FC70 / (FC70_Thing) FRT_46_106_148_128* / P12i / (P9i|P10)*
{code:title=Rules}
x <rdf:type> <rso:FC70_Thing>; x <crm:P12i_was_present_at> y => x <rso:FR12_was_present_at> y
x <rdf:type> <rso:FC70_Thing>; x <crm:P12i_was_present_at> y; y <rso:FRT9i_10> z => x <rso:FR12_was_present_at> z
x <rdf:type> <rso:FC70_Thing>; x <rso:FRT_46_106_148_128> y; y <crm:P12i_was_present_at> z => x <rso:FR12_was_present_at> z
x <rdf:type> <rso:FC70_Thing>; x <rso:FRT_46_106_148_128> y; y <crm:P12i_was_present_at> z; z <rso:FRT9i_10> t => x <rso:FR12_was_present_at> t
{code}

h4. Navigating the Event Hierarchy
{jira:RS-1832}
"Thing present at Ancient Egypt" (thes:x107598) should find all:
- things produced in that culture/period, eg GAA42731
- things produced in any sub-period thereof, eg GAA86605 (which is from the 26th Dynasty)

The data is like this:
{section}
{column}
{noformat}
<GAA42731> P108i_was_produced_by <GAA42731/production>.
<GAA42731/production> P9_consists_of <GAA42731/production/2>.
<GAA42731/production/2> P10_falls_within thes:x107598.
thes:x107598 skos:broader thes:x112519.
{noformat}
{column}
!FR12_was_present_at_data.png!
{column}
{section}

The BM data has some inconsistencies:
# As reported at [FR Transitivity#From Period]: the Period thesaurus uses only skos:broader but not P9_consists_of to make the hierarchy.
We fixed this in FRs in Jun 2013 with the file FR-Transitivity.ttl
# As reported at [BM Association Mapping Problems#Production sub-event not connected] in Jul 2013: there's no direct link between <GAA42731> and <GAA42731/production/2>.
I don't believe any of the problems reported on that page are fixed by BM

To cater to these inconsistencies, the FRs loop by (P9,P10,skos:broader)* which means:
If present at an event, a thing is considered to also be present at:
- sub-events (P9)
- super-periods (P10)
- their super-periods (skos:broader)

But as you see, the hierarchy is navigated *up and down*, which violates principles of covariance.
{warning}
If a data provider uses P9_consists_of instead of skos:broader to connect Periods (whcih is the *right* thing), the following false inference will result:
- GAA42731 was present at Ancient Egypt, therefore it was present at all its sub-periods, eg 26th Dynasty
{warning}

{section}
{column}
In 2 above we have asked the production sub-events to be directly connected to the object.
Then we'd navigate upward and the P9 link is never used:
!FR12_was_present_at_data1.png!
{column}
{column}
In fact the main production <GAA42731/production> is parasitic since it carries no data.
So you can dismiss it, simplifying the representation:
!FR12_was_present_at_data2.png!
{column}
{section}


h4. Navigating the Part Hierarchy

h45. Representing Acquisition
An acquisition can be modeled as an event having all these classes:
- E8_Acquisition: thing changes ownership
- the buyer's collection: E79

h45. BUG
The loop P46i_forms_part_of causes a serious problem if E79_Part_Addition is used. Assume Thing1 and Thing2 are part of the BM_collection, THEN:
{noformat}
This also causes quadratic growth of the repository, and seemingly exponential growth of loading times.

h45. How to Fix
Cannot be fixed easily using negation: "P46i_forms_part_of <thing> where <thing> is not E78_Collection":
- Class negation causes much higher inferencing complexity in OWL
Corrections:
- Original definition Includes P33_used_specific_technique/P68_foresees_use_of, but I think that is far-fetched: P33 should refer to an explicitly defined procedure, and if P68 then it stands to reason the material was actually P126_employed!
- I use P31i_was_modified_by instead of P92i_was_brought_into_existence_by to also catch repairs
- I use the same beginning as [#Thing created by Actor- FR92i_created_by] to also catch repairs (P31i_was_modified_by).
(P94i_was_created_by is superfluous here, but doesn't hurt)

Implementation:
- FR45_is_made_of := (FC70) FRT_46_106_148* / (P45_consists_of | P31i_was_modified_by/P126_employed)
- FR45_is_made_of := (FC70_Thing) FRT_46_106_148_128* / P45_consists_of |
FRX92i_created / P126_employed
{code:title=Rules}
x <rdf:type> <rso:FC70_Thing>; x <crm:P45_consists_of> y => x <rso:FR45_is_made_of> y
x <rso:FRT_46_106_148_128> y; y <crm:P45_consists_of> z => x <rso:FR45_is_made_of> z
x <rdf:type> <rso:FC70_Thing>; x <crm:P31i_was_modified_by> <rso:FRX92i_created> y; y <crm:P126_employed> z => x <rso:FR45_is_made_of> z
x <rdf:type> <rso:FRT_46_106_148>; x <crm:P45_consists_of> y => x <rso:FR45_is_made_of> y
x <rdf:type> <rso:FRT_46_106_148>; x <crm:P31i_was_modified_by> y; y <crm:P126_employed> z => x <rso:FR45_is_made_of> z
{code}

h3. Thing used technique- FR32_used_technique
The production/modification of Thing (or part thereof) used general technique
!FR32_used_technique-fixed.png!
- This is an extension defined by me
- Similarly to [#Thing is made of Material- FR45_is_made_of], it uses the same beginning as [#Thing created by Actor- FR92i_created_by].
P94i_was_created_by may be useful here: an immaterial feature on the object (eg Inscription) may be made using a specific technique,
- (I think P32_used_general_technique is more useful than P33_used_specific_technique, see [#Thing is made of Material- FR45_is_made_of] above)

Implementation:
- FR32_used_technique := FRX92i_created / P32_used_general_technique
{code:title=Rules}
x <rso:FRX92i_created> y; y <crm:P32_used_general_technique> z => x <rso:FR32_used_technique> z
{code}

h3. Thing is/has Type- FR2_has_type
Thing has Type (or has shape, is of kind, is about subject, etc)

Implementation:
- FRX2_has_type := (FC70_Thing) / FRT_46_106_148_128* / (P2_has_type | P67_refers_to) / (E55_Type) P67_refers_to (E55_Type))
{code:title=Rules}
x <rdf:type> <rso:FC70_Thing>; x <crm:P2_has_type> y => x <rso:FRX2_has_type> y
but our search UI currently has a restriction that the many-to-many relation "FRs-thesauri" should split both FRs and thesauri into equivalence classes.

h3. Thing used technique- FR32_used_technique
The production/modification of Thing (or part thereof) used general technique
!FR32_used_technique-fixed.png!
- This is an extension defined by me
- (I think P32_used_general_technique is more useful than P33_used_specific_technique, see [#Thing is made of Material- FR45_is_made_of] above)

Implementation:
- FR32_used_technique := (FC70_Thing) FRT_46_106_148* / P31i_was_modified_by / P32_used_general_technique
{code:title=Rules}
x <rdf:type> <rso:FC70_Thing>; x <crm:P31i_was_modified_by> y; y <crm:P32_used_general_technique> z => x <rso:FR32_used_technique> z
x <rdf:type> <rso:FRT_46_106_148>; x <crm:P31i_was_modified_by> y; y <crm:P32_used_general_technique> z => x <rso:FR32_used_technique> z
{code}

h3. Thing identified by Identifier- FR1_identified_by
Thing (or part thereof) has Identifier (exact-match string).
- FRX_label := P3 | rdfs:label
Using such intermediate relation is very stupid, since it will double the number of label triples & literals in the repo

h2. Thing-Image
In order to make access to images for display easier, and [FR Enhancements#Search by Image] faster, we implement two FRs according to the definitions in [Search Result Fields#Display Fields]

- rso:FR_main_representation: main image (denoted ?Image)
{code:title=Rule}
E <rdf:type> <rso:FC70_Thing>
E <crm:P70i_is_documented_in> doc
doc <crm:P138i_has_representation> img
img <rdf:type> <rso:E38_Main_Image>
img <crm:P1_is_identified_by> img1
img1 <crm:P2_has_type> <http://www.researchspace.org/thesaurus/identifier/nuxeo_uid>
img1 <crm:P3_has_note> Image
-------------------------------
E <rso:FR_main_representation> Image
{code}
{code:title=Rule}
E <rdf:type> <rso:FC70_Thing>
E <bmo:PX_has_main_representation> Image
Image <rdf:type> <crm:E38_Image>
-------------------------------
E <rso:FR_main_representation> Image
{code}

- rso:FR138i_representation: all images (denoted ?Images)
{code:title=Rule}
E <rdf:type> <rso:FC70_Thing>
E <crm:P70i_is_documented_in> doc
doc <crm:P138i_has_representation> img
img <rdf:type> <crm:E38_Image>
img <crm:P1_is_identified_by> img1
img1 <crm:P2_has_type> <http://www.researchspace.org/thesaurus/identifier/nuxeo_uid>
img1 <crm:P3_has_note> Image
-------------------------------
E <rso:FR138i_representation> Image
{code}
{code:title=Rule}
E <rdf:type> <rso:FC70_Thing>
E <crm:P138i_has_representation> Image
Image <rdf:type> <crm:E38_Image>
-------------------------------
E <rso:FR138i_representation> Image
{code}