Should you require any more information or have encountered a problem, please call the support helpdesk on (07) 5456 6000.

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 13 Next »

The models and contexts in GELLO can be bespoke, that is they can be custom designed for a given implementation. In health FHIR could well be one such model, instead of the HL7 V2 VMR Medical Objects uses.

This section describes some simple two level models built and implemented against, in various non-health domains, purely by way of example.

What could be the advantages of using a functional approach like GELLO? Advantages people talk about include being side effect free, referentially transparent, loops can be done recursively (and can be tail recursive), programming style is declarative and functions are pure. Another advantage of GELLO is that is is fairly obscure so there is much less risk with importing dependencies.

Engineering example

This first example will walk through an idea of building a small mechanical engineering ontology that started life with reference to https://fastenerengineering.com/what-are-pins/ . This ontology then will be used in a GELLO query along with information model instance data.

Engineering ontology

The ontology was created using a traditional Concepts, Descriptions and Relationships table approach, which also borrowed column headers from SNOMED, to allow an easier import into a terminology server used to SNOMED. 97 concepts were assigned random alphanumeric identifiers and given hierarchical types:

A similar number of relationships were made, mostly of the Is_A type:


This example will be about a type of fastener called a grooved pin coded internally to 9377156411. A small parent child table about grooved pins, coiled pins, dowel pins, cotter pins, split pins and slotted pins (phew!) was made and saved as an imported csv file. This has five levels of hierarchy with parents of Pin (Part), Fastener (Part) , Part (BuiltThing) and BuiltThing (BuiltThing). There is a second hierarchy going through 6253914735 | MechanicalFirmLinkage (BuiltThing) | . This table serves as a small reference terminology or ontology and the GELLO will make an appeal to it. It could be further populated out of the Relationships table. The table will be used in the code to return a boolean if a child and a parent concept are in the same row. The table is shown here:

Engineering schema

The information model was built as a gello_model and an XSD schema. Here is the gello_model:

Package OntoEngineering
Imports iso_21090_datatypes

    class Geometry extends Any
      name: String
      code: CD -- square, rectangle, circle, triangle, cylinder, cone, sphere, line , cube, cuboid
      area: PQ   --derived
      width: PQ
      length: PQ
      height: PQ
      volume: PQ  --derived
      radius: PQ
      circumference: PQ
      describingFunction: String
 --all horizontal relationships done up to here

    class BuiltThing extends Any
      code: CD
      hasGeometry: Sequence(Geometry)
      hasBehaviour: Behaviour
      hasRole: Role
      component: Sequence(Component)
      tensileStrength: PQ
      btArea: PQ
      btWidth: PQ
      btLength: PQ
      btVolume: PQ
      btRadius: PQ
      btCircumference: PQ
      btFluxEmmission: PQ
      spaceType: CD  -- negative, positive, negAndPos
      constructionMaterial: CD  -- wood, steel
      constructionMethod: CD  --  extruded, printed, cast, milled
      elasticity: PQ

    class Part extends BuiltThing
      partID: String
      usedWith: Sequence(Part)

    class Behaviour extends Any

    class Role extends Any
      participant1: Part
      participant2: Part
      roleType: CD -- fasten, support, join

    class Component extends Part
      componentID: String

    class Fastener extends Part  --reference https://fastenerengineering.com/what-are-pins/
      type: CD  --mechanical, electromagnetic, adhesive

    class Pin extends Fastener
      pinType: CD -- dowel, slotted, coiled (spiral), grooved, split, cotter
      chamfer: Chamfer

    class Chamfer extends Any
      angle: PQ
      chamferLength: PQ
      turnOffDistance: PQ
      chamferLocation: CD  -- proximal, distal

    class SpringPin extends Pin  --new
      springStrength: PQ

    class SlottedPin extends SpringPin
      sheetRevolutionDeg: PQ
      compressionTolerance: PQ

    class CoiledPin extends SpringPin
        -- sheetRevolutionDeg > 360 deg

    class GroovedPin extends Pin
      grooveNumber: Integer  --usually 3    -- done
      groove: Sequence(Component)

    class CotterPin extends Any
      taper: Geometry

    class SplitPin extends Pin
      end: Sequence(Component)

    class Bush extends Part
      -- spaceType = negative
      interferenceMeasure: PQ
      chamfer: Chamfer

    class InfrastructureRoot extends Any
       builtThing: Sequence(BuiltThing)

EndPackage


Data

A xml file was created that accords with the model:

<GroovedPin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <type
        code="5336670848"
        codeSystem="2.16.840.1.113883.6.8"
        codeSystemName="OntoEValueDomain">
        <displayName value = "Mechanical" />
    </type>
    <pinType
        code="9377156411"
        codeSystem="2.16.840.1.113883.6.8"
        codeSystemName="OntoEValueDomain">
        <displayName value = "Grooved Pin" />    
    </pinType>
    <partID value = '6787982-A'/>
    <hasGeometry> 
            <code
                code="7573194557"
                codeSystem="2.16.840.1.113883.6.8"
                codeSystemName="OntoEValueDomain">
                <displayName value = "Cylinder"/>
            </code>
    </hasGeometry>
    <spaceType
            code="8494431267"
            codeSystem="2.16.840.1.113883.6.8"
            codeSystemName="OntoEValueDomain">
            <displayName value = "PositiveSpace"/>    
    </spaceType>
    <btLength xsi:type = "PQ" value = "100" unit = "mm" />
    <btRadius xsi:type = "PQ" value = "10" unit = "mm" />
    <hasRole>
        <roleType code="4514449250"
                  codeSystem="2.16.840.1.113883.6.8"
                  codeSystemName="OntoEValueDomain">
                  <displayName value = "Fasten"/>
    </roleType>
    </hasRole>
    <usedWith>
        <partID value = '89u207-F'/>
        <code
            code="7715218853"
            codeSystem="2.16.840.1.113883.6.8"
            codeSystemName="OntoEValueDomain">
            <displayName value = "Bush"/>
        </code>
    </usedWith>
    <component>
        <componentID value = 'Groove1'/>
        <hasGeometry> 
            <code
                code="7573194557"
                codeSystem="2.16.840.1.113883.6.8"
                codeSystemName="OntoEValueDomain">
                <displayName value = "Cylinder"/>
            </code>
        </hasGeometry>
        <spaceType
            code="8999051355"
            codeSystem="2.16.840.1.113883.6.8"
            codeSystemName="OntoEValueDomain">
            <displayName value = "NegativeSpace"/>    
        </spaceType>
        <btLength xsi:type = "PQ" value = "75" unit = "mm" />
        <btRadius xsi:type = "PQ" value = "4" unit = "mm" />
    </component>

    
    <grooveNumber value = '1' />
</GroovedPin>

This data instance is about a grooved pin with one groove. The idea of a grooved pin is that is has two or more grooves usually which compress when the pin is inserted with force into a preformed hole, in this case a 'bush'. They are meant to not move. So there is a risk if the groove number is wrong as this part could slip due to a lack of friction in the linkage. At a semantic level we want a firm mechanical linkage and therefore want to use the correct part - would we discover that a grooved pin is a firm linkage if we looked it up in mechanical engineering textbooks? This is what the semantic appeal will attempt to address.

So lets move onto the actual GELLO:

GELLO

Imports OntoEngineering, DB.OntoEngineeringParentChildTable
Context GroovedPin

--validation rules:
Let groovedPinConcept:CD = pinType
Let grooveNumberOk: Boolean = grooveNumber >= 2
Let partTypeOk: Boolean  = type.displayName.value = 'Mechanical'
Let correctAssocPart: Boolean = usedWith->exists(code.displayName.value='Bush')

--implies
Let mechanicalFirmLinkage_Concept: CD = CD{code = '6253914735',
                                           codeSystem ='3.16.840.1.113883.6.8',
                                           codeSystemName = 'OntoEValueDomain',
                                           displayName = ST{value = 'Mechanical Firm Linkage'}}
Let groovedPin_Concept: CD = CD{code = '9377156411',
                                codeSystem ='3.16.840.1.113883.6.8',
                                codeSystemName = 'OntoEValueDomain',
                                displayName = ST{value = 'Grooved Pin'}} 
Let test: Boolean = groovedPinConcept = groovedPin_Concept
Let parentConcept: CD = mechanicalFirmLinkage_Concept
Let childConcept: CD = groovedPin_Concept
Let ontoETable: Sequence(TBL.csv)= csv
Let selectedRowOrRows: Sequence(TBL.csv) =
         ontoETable->select((LeafID = childConcept.code.toReal())
                             and (
                                  (If Parent1.oclIsDefined() then Parent1 = parentConcept.code.toReal() else False endif) or
                                  (If Parent2.oclIsDefined() then Parent2 = parentConcept.code.toReal() else False endif) or
                                  (If Parent3.oclIsDefined() then Parent3 = parentConcept.code.toReal() else False endif) or
                                  (If Parent4.oclIsDefined() then Parent4 = parentConcept.code.toReal() else False endif) or
                                  (If Parent5.oclIsDefined() then Parent5 = parentConcept.code.toReal() else False endif) or
                                  (If Parent6.oclIsDefined() then Parent6 = parentConcept.code.toReal() else False endif) or
                                  (If Parent7.oclIsDefined() then Parent7 = parentConcept.code.toReal() else False endif) or
                                  (If Parent8.oclIsDefined() then Parent8 = parentConcept.code.toReal() else False endif))
                                 )
Let impliesBoolean: Boolean = selectedRowOrRows.size()>0

-- result
Tuple { checkGrooveNumber = grooveNumberOk ,
        checkPartTyping =  partTypeOk,
        checkUsedWith = correctAssocPart,
        checkSemantics = impliesBoolean
        }


and here is the result:



  • No labels