Module: Causalontology::Canonical
- Defined in:
- lib/causalontology/canonical.rb
Constant Summary collapse
- IDENTITY_FIELDS =
The identity-bearing fields of each of the seventeen kinds. "type" is always injected, so it is not listed here. Order does not matter (JCS sorts keys).
{ # ---- type tier ---- "occurrent" => ["label", "category", "stratum"], "causal_relation_object" => ["causes", "effects", "mechanism", "temporal", "modality", "context", "refines", "skips"], "continuant" => ["label", "category"], "realizable" => ["kind", "bearer", "label"], "stratum" => ["label", "scheme", "ordinal", "unit", "governs"], "bridge" => ["coarse", "fine", "relation"], "port" => ["bearer", "label", "direction", "accepts", "realizable"], "conduit" => ["label", "from", "to", "carries", "transform"], "quality" => ["label", "datatype", "unit", "stratum"], # ---- token tier ---- "token_individual" => ["instantiates", "designator", "part_of"], "token_occurrence" => ["instantiates", "interval", "participants", "locus", "observer"], "state_assertion" => ["subject", "quality", "value", "interval"], "token_causal_claim" => ["causes", "effects", "covering_law", "actual_delay", "counterfactual"], # ---- provenance tier ---- "assertion" => ["about", "source", "evidence_type", "evidence", "strength", "confidence", "timestamp", "evidenced_by"], "enrichment" => ["about", "field", "entry", "source", "timestamp"], "retraction" => ["retracts", "source", "timestamp"], "succession" => ["predecessor", "successor", "timestamp"], }.freeze
- PREFIX =
Whole-word re-mint (P7): the scheme IS the type value for every kind.
IDENTITY_FIELDS.keys.each_with_object({}) { |k, h| h[k] = k }.freeze
- KIND_OF_PREFIX =
PREFIX.invert.freeze
Class Method Summary collapse
-
.canonicalize(obj, kind = nil) ⇒ Object
The RFC 8785 identity-bearing bytes of an object (a UTF-8 string).
-
.identify(obj, kind = nil) ⇒ Object
The content-addressed identifier: scheme + ":" + SHA-256 hex.
-
.identity_bearing(obj, kind = nil) ⇒ Object
The identity-bearing subset of an object, with type always present.
-
.infer_kind(obj) ⇒ Object
Infer an object's kind from its type field, id prefix, or shape.
Class Method Details
.canonicalize(obj, kind = nil) ⇒ Object
The RFC 8785 identity-bearing bytes of an object (a UTF-8 string).
88 89 90 91 |
# File 'lib/causalontology/canonical.rb', line 88 def canonicalize(obj, kind = nil) _, ib = identity_bearing(obj, kind) Jcs.encode(ib).encode(Encoding::UTF_8) end |
.identify(obj, kind = nil) ⇒ Object
The content-addressed identifier: scheme + ":" + SHA-256 hex.
94 95 96 97 98 |
# File 'lib/causalontology/canonical.rb', line 94 def identify(obj, kind = nil) kind, ib = identity_bearing(obj, kind) digest = Digest::SHA256.hexdigest(Jcs.encode(ib).encode(Encoding::UTF_8)) PREFIX[kind] + ":" + digest end |
.identity_bearing(obj, kind = nil) ⇒ Object
The identity-bearing subset of an object, with type always present. Returns [kind, subset].
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/causalontology/canonical.rb', line 75 def identity_bearing(obj, kind = nil) kind ||= infer_kind(obj) unless IDENTITY_FIELDS.key?(kind) raise ArgumentError, "unknown kind: #{kind.inspect}" end out = { "type" => kind } IDENTITY_FIELDS[kind].each do |field| out[field] = obj[field] if obj.key?(field) end [kind, out] end |
.infer_kind(obj) ⇒ Object
Infer an object's kind from its type field, id prefix, or shape.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/causalontology/canonical.rb', line 54 def infer_kind(obj) return obj["type"] if obj.key?("type") if obj.key?("id") && obj["id"].is_a?(String) && obj["id"].include?(":") pre = obj["id"].split(":", 2)[0] return KIND_OF_PREFIX[pre] if KIND_OF_PREFIX.key?(pre) end return "bridge" if obj.key?("coarse") && obj.key?("fine") return "causal_relation_object" if obj.key?("causes") && obj.key?("effects") return "retraction" if obj.key?("retracts") return "succession" if obj.key?("predecessor") && obj.key?("successor") return "enrichment" if obj.key?("field") && obj.key?("entry") return "assertion" if obj.key?("evidence_type") || (obj.key?("about") && obj.key?("confidence")) return "realizable" if obj.key?("kind") && obj.key?("bearer") raise ArgumentError, "cannot infer kind (occurrents and continuants share a shape); " \ "pass kind explicitly" end |