Repository navigation
Notation Format
Notation is the token-efficient text that Noema puts in a prompt. It is line-oriented, with one fact per line and no filler words.
#1 Larry Page :PERSON
#2 Google :ORG
#3 Sundar Pichai :PERSON
#1 -found-> #2
#3 -ceo_of-> #2
notation := entity_line* relation_line* event_line*
entity_line := "#" id " " name " :" TYPE
relation_line := "#" subject_id " -" predicate "-> #" object_id
event_line := "*" label " (" "#" id ("," "#" id)* ")" [" @" time]
id := digits
TYPE := PERSON | ORG | GPE | LOC | DATE | EVENT | PRODUCT | MONEY | OTHER
| Line | Example | Meaning |
|---|---|---|
| Entity | #2 Google :ORG |
Declares entity 2, named Google, of type ORG |
| Relation | #1 -found-> #2 |
Entity 1 has the relation found to entity 2 |
| Event | *ipo (#2) @2004-08-19 |
An event ipo involving entity 2, on a date |
-
Ids are local.
#1,#2and so on are sequential integers scoped to one notation block. They are not the longent_...ids in the graph, and the same entity can have a different local id in the next retrieval. - Declare before use. Every entity is declared on an entity line before any relation or event refers to it, so notation parses in one top-to-bottom pass.
- Entities, then relations, then events. Lines appear in that order.
-
Predicates are lowercase snake_case, such as
found,ceo_oforheadquarter_in. -
Isolated entities are left out. When encoding a whole graph, entities with no relation or
event are dropped, since there is no fact to compress. Pass explicit
entity_idsto include them.
import noema
notation = noema.encode_graph(graph) # the whole graph
notation = noema.encode_graph(graph, entity_ids=[eid1]) # a chosen sub-graphretrieve() does this for you on the retrieved sub-graph. Use encode_graph() directly when
you build or filter a SemanticGraph yourself.
parsed = noema.parse_notation(notation)
parsed.entities # dict: local id -> NotationEntity (local_id, name, type)
parsed.relations # list of NotationRelation (subject_id, predicate, object_id)
parsed.events # list of NotationEvent (label, participant_ids, time)parse_notation() raises ValueError with the line number for a malformed line, or for a
relation or event that refers to an entity not yet declared.
text = noema.decode(notation)decode() writes one sentence per relation in notation order, then one per event. It is
template-based, not a generative model. Predicates are turned into phrases by simple rules:
| Predicate | Decoded phrase |
|---|---|
found |
found |
ceo_of |
is the ceo of |
headquarter_in |
is headquarter in |
So #3 -ceo_of-> #2 decodes to "Sundar Pichai is the ceo of Google." The output is readable but
grammatically rough. It is meant for validation and for models that prefer prose, not for
display to end users. Relations that share a subject are not merged into one sentence.