diff --git a/src/ofn_2_ldtab/axiom_translation.rs b/src/ofn_2_ldtab/axiom_translation.rs index d249239..e8307e0 100644 --- a/src/ofn_2_ldtab/axiom_translation.rs +++ b/src/ofn_2_ldtab/axiom_translation.rs @@ -1,6 +1,7 @@ use crate::ofn_2_ldtab::annotation_translation; use crate::ofn_2_ldtab::class_translation; use crate::ofn_2_ldtab::property_translation; +use crate::ofn_2_ldtab::rule_translation; use crate::ofn_2_ldtab::util; use rand::Rng; use serde_json::json; @@ -1071,6 +1072,30 @@ pub fn translate_annotation_assertion_axiom(v: &Value) -> Value { } } +pub fn translate_rule(v: &Value) -> Value { + + let owl = annotation_translation::get_owl(v); + let ofn_annotations = annotation_translation::get_annotations(v); + let annotation = annotation_translation::translate_annotations(&ofn_annotations); + + let body = rule_translation::translate(&owl[1]); + let head = rule_translation::translate(&owl[2]); + + //subject is a blank node (that needs to be a hash of the rule) + + let triple = json!({ + "assertion":"1", + "retraction":"0", + "graph":"graph", + "subject":"_:gen", + "predicate":"owl:versionIRI", + "object":body, + "datatype":"_IRI", + "annotation": annotation //NOTE: this deviates from ldtab.clj + }); + triple +} + pub fn translate_ontology(v: &Value) -> Value { let iri = &v[1]; let viri = &v[2]; diff --git a/src/ofn_2_ldtab/mod.rs b/src/ofn_2_ldtab/mod.rs index bf96de3..0ecdbbc 100644 --- a/src/ofn_2_ldtab/mod.rs +++ b/src/ofn_2_ldtab/mod.rs @@ -1,6 +1,7 @@ -pub mod util; +pub mod annotation_translation; pub mod axiom_translation; pub mod class_translation; +pub mod rule_translation; pub mod property_translation; -pub mod annotation_translation; pub mod translation; +pub mod util; diff --git a/src/ofn_2_ldtab/rule_translation.rs b/src/ofn_2_ldtab/rule_translation.rs new file mode 100644 index 0000000..cb20238 --- /dev/null +++ b/src/ofn_2_ldtab/rule_translation.rs @@ -0,0 +1,104 @@ +use crate::ofn_2_ldtab::util; +use crate::ofn_2_ldtab::property_translation; +use crate::ofn_2_ldtab::class_translation; +use serde_json::json; +use serde_json::{Map, Value}; + + +pub fn translate(v: &Value) -> Value { + match v[0].as_str() { + Some("Body") => translate_body(v), + Some("Head") => translate_head(v), + Some("ObjectPropertyAtom") => translate_object_property_atom(v), + Some(_) => json!("TODO"), + //None => owl::OWL::Named(String::from(v.as_str().unwrap())), + + //Some("Variable") => axiom_translation::translate_ontology(v), + //Some("SameIndividualAtom") => axiom_translation::translate_ontology(v), + //Some("DifferentIndividualsAtom") => axiom_translation::translate_ontology(v), + //Some("DataRangeAtom") => axiom_translation::translate_ontology(v), + //Some("ClassAtom") => axiom_translation::translate_ontology(v), + //Some("BuiltInAtom") => axiom_translation::translate_ontology(v), + // + None => translate_named_entity(&v), + } +} + +pub fn translate_named_entity(v: &Value) -> Value { + let o: String = String::from(v.as_str().unwrap()); + json!(o) +} + +pub fn get_object(v: &Value) -> Value { + let o: Value = translate(&v); + let d: String = String::from(util::translate_datatype(&v).as_str().unwrap()); + + json!({"object" : o, + "datatype" : d}) +} + +pub fn translate_object_property_atom(v: &Value) -> Value { + let type_o = get_object(&json!("swrl:IndividualPropertyAtom")); + let property_o = get_object(&v[1]); + let arg1_o = get_object(&v[2]); + let arg2_o = get_object(&v[3]); + json!( {"datatype" : "_JSON", + "object": vec![json!({"rdf:type" : vec![type_o], + "swrl:propertyPredicate" : vec![property_o], + "swrl:argument1" : vec![arg1_o], + "swrl:argument2" : vec![arg2_o]})]}) +} + +pub fn translate_body(v: &Value) -> Value { + + let array = v.as_array().unwrap(); + let args = array[1..].to_vec(); + + let mut map = Map::new(); + + for arg in args.iter().rev() { + if map.is_empty() { //first element + let rest_o: Value = get_object(&json!("rdf:nil")); + let type_o: Value = get_object(&json!("swrl:AtomList")); + map.insert(String::from("rdf:rest"),json!(vec![rest_o])); + map.insert(String::from("rdf:type"),json!(vec![type_o])); + map.insert(String::from("rdf:first"),json!(vec![translate(arg)])); + } else { + let inner = map.clone(); + map.clear(); + let type_o: Value = get_object(&json!("swrl:AtomList")); + map.insert(String::from("rdf:type"),json!(vec![type_o])); + map.insert(String::from("rdf:first"),json!(vec![translate(arg)])); + map.insert(String::from("rdf:rest"),json!(vec![json!(inner)])); + } + } + + json!({"swrl:body" : vec![map]}) +} + +pub fn translate_head(v: &Value) -> Value { + + let array = v.as_array().unwrap(); + let args = array[1..].to_vec(); + + let mut map = Map::new(); + + for arg in args.iter().rev() { + if map.is_empty() { //first element + let rest_o: Value = get_object(&json!("rdf:nil")); + let type_o: Value = get_object(&json!("swrl:AtomList")); + map.insert(String::from("rdf:rest"),json!(vec![rest_o])); + map.insert(String::from("rdf:type"),json!(vec![type_o])); + map.insert(String::from("rdf:first"),json!(vec![translate(arg)])); + } else { + let inner = map.clone(); + map.clear(); + let type_o: Value = get_object(&json!("swrl:AtomList")); + map.insert(String::from("rdf:type"),json!(vec![type_o])); + map.insert(String::from("rdf:first"),json!(vec![translate(arg)])); + map.insert(String::from("rdf:rest"),json!(vec![json!(inner)])); + } + } + + json!({"swrl:head" : vec![map]}) +} diff --git a/src/ofn_2_ldtab/translation.rs b/src/ofn_2_ldtab/translation.rs index ff3d6ab..3e6713d 100644 --- a/src/ofn_2_ldtab/translation.rs +++ b/src/ofn_2_ldtab/translation.rs @@ -1,20 +1,18 @@ -use serde_json::{Value}; -use crate::ofn_2_ldtab::axiom_translation as axiom_translation; -use crate::ofn_2_ldtab::util as util; - +use crate::ofn_2_ldtab::axiom_translation; +use crate::ofn_2_ldtab::util; +use serde_json::Value; /// Given an OFN S-expression (encoded in JSON), /// return its corresponding LDTab ThickTripe /// /// Examples /// -/// let ofn_string = r#"["SubClassOf","obo:IAO_0000120",["ObjectSomeValuesFrom","obo:BFO_0000050","obo:OBI_0500000"]]"#; +/// let ofn_string = r#"["SubClassOf","obo:IAO_0000120",["ObjectSomeValuesFrom","obo:BFO_0000050","obo:OBI_0500000"]]"#; /// let ofn = util::parser::parse(&ofn_string); /// let thick_triple = ofn_2_ldtab::translation::ofn_2_thick_triple(&ofn); -/// println!("{}", thick_triple); -/// -pub fn ofn_2_thick_triple(v : &Value) -> Value { - +/// println!("{}", thick_triple); +/// +pub fn ofn_2_thick_triple(v: &Value) -> Value { let ldtab_triple = match v[0].as_str() { Some("Declaration") => axiom_translation::translate_declaration(v), Some("DatatypeDefinition") => axiom_translation::translate_datatype_definition(v), @@ -24,20 +22,42 @@ pub fn ofn_2_thick_triple(v : &Value) -> Value { Some("EquivalentClasses") => axiom_translation::translate_equivalent_classes_axiom(v), Some("SubObjectPropertyOf") => axiom_translation::translate_sub_object_property(v), Some("SubDataPropertyOf") => axiom_translation::translate_sub_data_property(v), - Some("EquivalentObjectProperties") => axiom_translation::translate_equivalent_properties_axiom(v), - Some("EquivalentDataProperties") => axiom_translation::translate_equivalent_properties_axiom(v), - Some("DisjointObjectProperties") => axiom_translation::translate_disjoint_properties_axiom(v), - Some("DisjointDataProperties") => axiom_translation::translate_disjoint_properties_axiom(v), - Some("InverseObjectProperties") => axiom_translation::translate_inverse_properties_axiom(v), - Some("FunctionalObjectProperty") => axiom_translation::translate_functional_property_axiom(v), - Some("FunctionalDataProperty") => axiom_translation::translate_functional_property_axiom(v), - Some("InverseFunctionalObjectProperty") => axiom_translation::translate_inverse_functional_object_property_axiom(v), - Some("ReflexiveObjectProperty") => axiom_translation::translate_reflexive_object_property_axiom(v), - Some("IrreflexiveObjectProperty") => axiom_translation::translate_irreflexive_object_property_axiom(v), - Some("SymmetricObjectProperty") => axiom_translation::translate_symmetric_object_property_axiom(v), - Some("AsymmetricObjectProperty") => axiom_translation::translate_asymmetric_object_property_axiom(v), - Some("TransitiveObjectProperty") => axiom_translation::translate_transitive_object_property_axiom(v), - Some("ObjectPropertyDomain") => axiom_translation::translate_object_property_domain_axiom(v), + Some("EquivalentObjectProperties") => { + axiom_translation::translate_equivalent_properties_axiom(v) + } + Some("EquivalentDataProperties") => { + axiom_translation::translate_equivalent_properties_axiom(v) + } + Some("DisjointObjectProperties") => { + axiom_translation::translate_disjoint_properties_axiom(v) + } + Some("DisjointDataProperties") => axiom_translation::translate_disjoint_properties_axiom(v), + Some("InverseObjectProperties") => axiom_translation::translate_inverse_properties_axiom(v), + Some("FunctionalObjectProperty") => { + axiom_translation::translate_functional_property_axiom(v) + } + Some("FunctionalDataProperty") => axiom_translation::translate_functional_property_axiom(v), + Some("InverseFunctionalObjectProperty") => { + axiom_translation::translate_inverse_functional_object_property_axiom(v) + } + Some("ReflexiveObjectProperty") => { + axiom_translation::translate_reflexive_object_property_axiom(v) + } + Some("IrreflexiveObjectProperty") => { + axiom_translation::translate_irreflexive_object_property_axiom(v) + } + Some("SymmetricObjectProperty") => { + axiom_translation::translate_symmetric_object_property_axiom(v) + } + Some("AsymmetricObjectProperty") => { + axiom_translation::translate_asymmetric_object_property_axiom(v) + } + Some("TransitiveObjectProperty") => { + axiom_translation::translate_transitive_object_property_axiom(v) + } + Some("ObjectPropertyDomain") => { + axiom_translation::translate_object_property_domain_axiom(v) + } Some("ObjectPropertyRange") => axiom_translation::translate_object_property_range_axiom(v), Some("DataPropertyDomain") => axiom_translation::translate_data_property_domain_axiom(v), @@ -46,25 +66,41 @@ pub fn ofn_2_thick_triple(v : &Value) -> Value { Some("DifferentIndividuals") => axiom_translation::translate_different_individuals_axiom(v), Some("HasKey") => axiom_translation::translate_has_key_axiom(v), Some("ClassAssertion") => axiom_translation::translate_class_assertion_axiom(v), - Some("ObjectPropertyAssertion") => axiom_translation::translate_object_property_assertion_axiom(v), - Some("NegativeObjectPropertyAssertion") => axiom_translation::translate_negative_object_property_assertion_axiom(v), - Some("DataPropertyAssertion") => axiom_translation::translate_object_property_assertion_axiom(v), - Some("NegativeDataPropertyAssertion") => axiom_translation::translate_negative_data_property_assertion_axiom(v), + Some("ObjectPropertyAssertion") => { + axiom_translation::translate_object_property_assertion_axiom(v) + } + Some("NegativeObjectPropertyAssertion") => { + axiom_translation::translate_negative_object_property_assertion_axiom(v) + } + Some("DataPropertyAssertion") => { + axiom_translation::translate_object_property_assertion_axiom(v) + } + Some("NegativeDataPropertyAssertion") => { + axiom_translation::translate_negative_data_property_assertion_axiom(v) + } Some("AnnotationAssertion") => axiom_translation::translate_annotation_assertion_axiom(v), - Some("SubAnnotationPropertyOf") => axiom_translation::translate_sub_annotation_property_of_axiom(v), - Some("AnnotationPropertyDomain") => axiom_translation::translate_annotation_property_domain_axiom(v), - Some("AnnotationPropertyRange") => axiom_translation::translate_annotation_property_range_axiom(v), + Some("SubAnnotationPropertyOf") => { + axiom_translation::translate_sub_annotation_property_of_axiom(v) + } + Some("AnnotationPropertyDomain") => { + axiom_translation::translate_annotation_property_domain_axiom(v) + } + Some("AnnotationPropertyRange") => { + axiom_translation::translate_annotation_property_range_axiom(v) + } Some("Import") => axiom_translation::translate_ontology_import(v), //TODO: ontology annotations - Some("OntologyAnnotation") => axiom_translation::translate_ontology_annotation(v), - Some("DocIRI") => axiom_translation::translate_doc_iri(v), - Some("Ontology") => axiom_translation::translate_ontology(v), + Some("OntologyAnnotation") => axiom_translation::translate_ontology_annotation(v), + Some("DocIRI") => axiom_translation::translate_doc_iri(v),//this is horned-owl specific + Some("Ontology") => axiom_translation::translate_ontology(v), + + Some("DLSafeRule") => axiom_translation::translate_rule(v), Some(_) => panic!(), None => panic!(), }; //ensure that all triples for LDTab conform to the same order - util::sort_value(&ldtab_triple) + util::sort_value(&ldtab_triple) }