Add some OWL ontology implementations
このコミットが含まれているのは:
コミット
b657bd2307
|
@ -1,6 +1,7 @@
|
|||
package rdf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
|
@ -25,6 +26,39 @@ type Vocabulary struct {
|
|||
Values map[string]VocabularyValue
|
||||
}
|
||||
|
||||
func (v *Vocabulary) SetType(name string, a *VocabularyType) error {
|
||||
if v.Types == nil {
|
||||
v.Types = make(map[string]VocabularyType, 1)
|
||||
}
|
||||
if _, has := v.Types[name]; has {
|
||||
return fmt.Errorf("name already exists for vocabulary Types")
|
||||
}
|
||||
v.Types[name] = *a
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Vocabulary) SetProperty(name string, a *VocabularyProperty) error {
|
||||
if v.Properties == nil {
|
||||
v.Properties = make(map[string]VocabularyProperty, 1)
|
||||
}
|
||||
if _, has := v.Properties[name]; has {
|
||||
return fmt.Errorf("name already exists for vocabulary Properties")
|
||||
}
|
||||
v.Properties[name] = *a
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Vocabulary) SetValue(name string, a *VocabularyValue) error {
|
||||
if v.Values == nil {
|
||||
v.Values = make(map[string]VocabularyValue, 1)
|
||||
}
|
||||
if _, has := v.Values[name]; has {
|
||||
return fmt.Errorf("name already exists for vocabulary Values")
|
||||
}
|
||||
v.Values[name] = *a
|
||||
return nil
|
||||
}
|
||||
|
||||
// VocabularyValue represents a value type that properties can take on.
|
||||
type VocabularyValue struct {
|
||||
Name string
|
||||
|
|
|
@ -1,23 +1,284 @@
|
|||
package owl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/cjslep/activity/tools/exp/rdf"
|
||||
)
|
||||
|
||||
const (
|
||||
owlSpec = "http://www.w3.org/2002/07/owl#"
|
||||
membersSpec = "members"
|
||||
disjointWithSpec = "disjointWith"
|
||||
unionOfSpec = "unionOf"
|
||||
importsSpec = "imports"
|
||||
ontologySpec = "Ontology"
|
||||
classSpec = "Class"
|
||||
objectPropertySpec = "ObjectProperty"
|
||||
functionalPropertySpec = "FunctionalProperty"
|
||||
)
|
||||
|
||||
type OWLOntology struct{}
|
||||
|
||||
func (o *OWLOntology) SpecURI() string {
|
||||
return "http://www.w3.org/2002/07/owl#"
|
||||
return owlSpec
|
||||
}
|
||||
|
||||
func (o *OWLOntology) Load() ([]rdf.RDFNode, error) {
|
||||
return nil, nil
|
||||
return o.LoadAsAlias("")
|
||||
}
|
||||
|
||||
func (o *OWLOntology) LoadAsAlias(s string) ([]rdf.RDFNode, error) {
|
||||
return nil, nil
|
||||
return []rdf.RDFNode{
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: owlSpec,
|
||||
Alias: s,
|
||||
Name: membersSpec,
|
||||
Delegate: &members{},
|
||||
},
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: owlSpec,
|
||||
Alias: s,
|
||||
Name: disjointWithSpec,
|
||||
Delegate: &disjointWith{},
|
||||
},
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: owlSpec,
|
||||
Alias: s,
|
||||
Name: unionOfSpec,
|
||||
Delegate: &unionOf{},
|
||||
},
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: owlSpec,
|
||||
Alias: s,
|
||||
Name: importsSpec,
|
||||
Delegate: &imports{},
|
||||
},
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: owlSpec,
|
||||
Alias: s,
|
||||
Name: ontologySpec,
|
||||
Delegate: &ontology{},
|
||||
},
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: owlSpec,
|
||||
Alias: s,
|
||||
Name: classSpec,
|
||||
Delegate: &class{},
|
||||
},
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: owlSpec,
|
||||
Alias: s,
|
||||
Name: objectPropertySpec,
|
||||
Delegate: &objectProperty{},
|
||||
},
|
||||
&rdf.AliasedDelegate{
|
||||
Spec: owlSpec,
|
||||
Alias: s,
|
||||
Name: functionalPropertySpec,
|
||||
Delegate: &functionalProperty{},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (o *OWLOntology) LoadElement(name string, payload map[string]interface{}) ([]rdf.RDFNode, error) {
|
||||
// TODO: Imports
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &members{}
|
||||
|
||||
type members struct{}
|
||||
|
||||
func (m *members) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
if !ctx.IsReset() {
|
||||
return true, fmt.Errorf("owl members entered without reset context")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (m *members) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// Finish adding the Current item to the resulting vocabulary
|
||||
if ctx.Current == nil {
|
||||
return true, fmt.Errorf("owl members exiting with nil Current")
|
||||
}
|
||||
switch v := ctx.Current.(type) {
|
||||
case *rdf.VocabularyType:
|
||||
if err := ctx.Result.Vocab.SetType(ctx.Name, v); err != nil {
|
||||
return true, err
|
||||
}
|
||||
case *rdf.VocabularyProperty:
|
||||
if err := ctx.Result.Vocab.SetProperty(ctx.Name, v); err != nil {
|
||||
return true, err
|
||||
}
|
||||
case *rdf.VocabularyValue:
|
||||
if err := ctx.Result.Vocab.SetValue(ctx.Name, v); err != nil {
|
||||
return true, err
|
||||
}
|
||||
default:
|
||||
return true, fmt.Errorf("owl members exiting with unhandled type: %T", ctx.Current)
|
||||
}
|
||||
ctx.Reset()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (m *members) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("owl members cannot be applied")
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &disjointWith{}
|
||||
|
||||
type disjointWith struct{}
|
||||
|
||||
func (d *disjointWith) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// Push the Current type aside, to build a Reference.
|
||||
if ctx.Current == nil {
|
||||
return true, fmt.Errorf("owl disjointWith enter given a nil Current")
|
||||
} else if _, ok := ctx.Current.(*rdf.VocabularyType); !ok {
|
||||
return true, fmt.Errorf("owl disjointWith enter not given a *rdf.VocabularyType")
|
||||
}
|
||||
ctx.Push()
|
||||
ctx.Current = &rdf.VocabularyReference{}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (d *disjointWith) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// Pop the Reference, put into the type.
|
||||
ref, ok := ctx.Current.(*rdf.VocabularyReference)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("owl disjointWith exit not given a *rdf.VocabularyReference")
|
||||
}
|
||||
ctx.Pop()
|
||||
vType, ok := ctx.Current.(*rdf.VocabularyType)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("owl disjointWith exit not given a *rdf.VocabularyType")
|
||||
}
|
||||
vType.DisjointWith = append(vType.DisjointWith, *ref)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (d *disjointWith) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("owl disjointWith cannot be applied")
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &unionOf{}
|
||||
|
||||
type unionOf struct{}
|
||||
|
||||
func (u *unionOf) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (u *unionOf) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (u *unionOf) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &imports{}
|
||||
|
||||
type imports struct{}
|
||||
|
||||
func (i *imports) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (i *imports) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (i *imports) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &ontology{}
|
||||
|
||||
type ontology struct{}
|
||||
|
||||
func (o *ontology) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (o *ontology) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (o *ontology) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// TODO
|
||||
return false, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &class{}
|
||||
|
||||
type class struct{}
|
||||
|
||||
func (c *class) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("owl class cannot be entered")
|
||||
}
|
||||
|
||||
func (c *class) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("owl class cannot be exited")
|
||||
}
|
||||
|
||||
func (c *class) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// Prepare a new VocabularyType in the context
|
||||
if !ctx.IsReset() {
|
||||
return true, fmt.Errorf("owl class applied with non-reset ParsingContext")
|
||||
}
|
||||
ctx.Current = &rdf.VocabularyType{}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &objectProperty{}
|
||||
|
||||
type objectProperty struct{}
|
||||
|
||||
func (o *objectProperty) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("owl objectProperty cannot be entered")
|
||||
}
|
||||
|
||||
func (o *objectProperty) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("owl objectProperty cannot be exited")
|
||||
}
|
||||
|
||||
func (o *objectProperty) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
// Prepare a new VocabularyProperty in the context
|
||||
if !ctx.IsReset() {
|
||||
return true, fmt.Errorf("owl objectProperty applied with non-reset ParsingContext")
|
||||
}
|
||||
ctx.Current = &rdf.VocabularyProperty{}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
var _ rdf.RDFNode = &functionalProperty{}
|
||||
|
||||
type functionalProperty struct{}
|
||||
|
||||
func (f *functionalProperty) Enter(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("owl functionalProperty cannot be entered")
|
||||
}
|
||||
|
||||
func (f *functionalProperty) Exit(key string, ctx *rdf.ParsingContext) (bool, error) {
|
||||
return true, fmt.Errorf("owl functionalProperty cannot be exited")
|
||||
}
|
||||
|
||||
func (f *functionalProperty) Apply(key string, value interface{}, ctx *rdf.ParsingContext) (bool, error) {
|
||||
if ctx.Current == nil {
|
||||
return true, fmt.Errorf("owl functionalProperty given nil Current in context")
|
||||
}
|
||||
prop, ok := ctx.Current.(*rdf.VocabularyProperty)
|
||||
if !ok {
|
||||
return true, fmt.Errorf("owl functionalProperty given Current that is not *rdf.VocabularyProperty")
|
||||
}
|
||||
prop.Functional = true
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -17,6 +17,27 @@ type JSONLD map[string]interface{}
|
|||
type ParsingContext struct {
|
||||
Result *ParsedVocabulary
|
||||
Current interface{}
|
||||
Name string
|
||||
Stack []interface{}
|
||||
}
|
||||
|
||||
func (p *ParsingContext) Push() {
|
||||
p.Stack = append([]interface{}{p.Current}, p.Stack...)
|
||||
}
|
||||
|
||||
func (p *ParsingContext) Pop() {
|
||||
p.Current = p.Stack[0]
|
||||
p.Stack = p.Stack[1:]
|
||||
}
|
||||
|
||||
func (p *ParsingContext) IsReset() bool {
|
||||
return p.Current == nil &&
|
||||
p.Name == ""
|
||||
}
|
||||
|
||||
func (p *ParsingContext) Reset() {
|
||||
p.Current = nil
|
||||
p.Name = ""
|
||||
}
|
||||
|
||||
type NameSetter interface {
|
||||
|
|
読み込み中…
新しいイシューから参照