This section opens the Reasoning layer, focusing on the operators and traversal patterns that act on the representation graphs introduced earlier. For path-oriented navigation, see Prototype Paths and Parameterization, and for their role in learning, read Shadows and Least General Generalization (LGG).
Relationships in ProtoScript define how Prototypes connect within the graph-based Buffaly system, forming the backbone of its dynamic, ontology-like structure. Unlike traditional ontologies, which rely on rigid class hierarchies and formal axioms, ProtoScript’s relationships are flexible, supporting a spectrum of connections—from simple, unlabeled links to complex, computed dependencies. This section introduces the taxonomy of relationships, detailing seven types: associative relationships, associations, cyclical relationships, type relationships (typeof), labeled properties, bidirectional relationships, and computed relationships. Each type builds on the previous, enabling developers to model real-world complexities with ease. Through examples rooted in familiar domains, we’ll explore how these relationships work, their syntax, and their advantages over traditional ontology frameworks, drawing analogies to C# and database concepts.
Relationships are the edges in ProtoScript’s graph, linking Prototype nodes to represent knowledge, behavior, and semantics. They enable:
- Complex Modeling: Capture intricate real-world connections, like family ties or database schemas.
- Dynamic Adaptability: Add or modify relationships at runtime, unlike static ontologies.
- Cross-Domain Integration: Connect code, data, and language within a unified graph.
- Reasoning: Discover patterns and transform data by traversing relationships.
ProtoScript’s relationships evolve without redefining schemas, applying structural traversal and a unified graph model instead of the fixed properties and axiomatic logic common in OWL-based systems.
For C# developers:
- Relationships are like class fields, properties, or navigation properties in an ORM, but organized in a graph with dynamic, multi-faceted connections.
- Think of ProtoScript as a graph-based ORM that links objects (Prototypes) in a flexible network, not just a database schema.
For JavaScript developers:
- Relationships resemble object properties in a JSON graph, where each Prototype links to others, supporting dynamic updates and complex traversals.
For database developers:
- Relationships are edges in a graph database, connecting nodes (Prototypes) to model entities and their interactions, with programmable logic.
ProtoScript’s relationships form a taxonomy, progressing from simple to complex. Below, we detail each type, its syntax, mechanics, and examples, using a consistent Simpsons dataset for clarity.
Purpose: Represent the simplest, unlabeled, unweighted connections between Prototypes, forming loose links without semantics.
Syntax: Implicitly defined by referencing Prototypes in collections or properties.
Details:
- No explicit weight or label, just a basic edge in the graph.
- Used for preliminary connections before adding meaning.
- C# Analogy: Like a
List<object>holding references without specific roles.
Example:
prototype Entity {
string Name = "";
}
prototype Group {
Collection Members = new Collection();
}
prototype Springfield_Group : Group {
Members = [Homer, Marge];
}
prototype Homer : Entity {
Name = "Homer Simpson";
}
prototype Marge : Entity {
Name = "Marge Simpson";
}
What’s Happening?
Springfield_Group.Memberslinks toHomerandMargewithout specifying why.- Graph View:
Springfield_Grouphas edges toHomerandMargenodes. - Unlike OWL’s need for defined properties, associative relationships allow quick, informal links.
Purpose: Add weight and bidirectionality to connections, forming explicit, stored relationships with minimal semantics.
Syntax:
prototype1.BidirectionalAssociate(prototype2);
Details:
- Creates mutual edges with a numeric weight (default 1), incremented by repeated associations.
- Stored as extensional facts in the graph.
- C# Analogy: Like a weighted adjacency list in a graph data structure.
Example:
prototype Food {
string Name = "";
}
prototype Turkey_Food : Food {
Name = "Turkey";
}
prototype Gravy_Food : Food {
Name = "Gravy";
}
Turkey_Food.BidirectionalAssociate(Gravy_Food);
What’s Happening?
Turkey_FoodandGravy_Foodare linked bidirectionally, with a weight of 1.- Graph View: Edges
Turkey_Food ↔ Gravy_Foodwith weight metadata. - Associations are simpler than OWL’s object properties, enabling rapid relationship setup.
Purpose: Enable bidirectional, cyclic property references, modeling mutual dependencies (e.g., a state and its cities).
Syntax:
prototype Type1 {
Type2 Property = new Type2();
}
prototype Type2 {
Collection Type1s = new Collection();
}
Details:
- Properties create loops (e.g.,
City.State → State,State.Cities → City). - Managed by the runtime to prevent infinite traversal.
- C# Analogy: Like circular object references (e.g.,
class City { State State; },class State { List<City> Cities; }).
Example:
prototype State {
string Name = "";
Collection Cities = new Collection();
}
prototype City {
string Name = "";
State State = new State();
}
prototype NewYork_State : State {
Name = "New York";
}
prototype NewYork_City : City {
Name = "New York City";
}
NewYork_City.State = NewYork_State;
NewYork_State.Cities.Add(NewYork_City);
What’s Happening?
NewYork_City.Statelinks toNewYork_State, andNewYork_State.Citieslinks back, forming a cycle.- Graph View:
NewYork_City ↔ NewYork_StateviaStateandCitiesedges. - Cycles are natural in ProtoScript, unlike OWL’s preference for acyclic hierarchies.
Purpose: Define directional inheritance relationships, checked by the typeof operator, to establish a Prototype’s place in the graph.
Syntax:
prototype Child : Parent;
if (prototype typeof Parent) { ... }
Details:
- Inheritance creates
isaedges, forming a DAG for type relationships. typeofchecks direct or transitive inheritance.- C# Analogy: Like
isor inheritance in C# (e.g.,class Child : Parent).
Example:
prototype Person {
string Name = "";
}
prototype Homer : Person {
Name = "Homer Simpson";
}
function IsPerson(Prototype proto) : bool {
return proto typeof Person;
}
What’s Happening?
Homer isa Person, andIsPerson(Homer)returnstrue.- Graph View:
Homerhas anisaedge toPerson. typeofenables dynamic type checks, simpler than OWL’s class assertions.
Purpose: Represent specific, named attributes linking Prototypes, storing extensional relationships.
Syntax:
Type Name = DefaultValue;
Details:
- Properties are named edges to other Prototypes or values, like database foreign keys.
- C# Analogy: Like class fields or navigation properties in Entity Framework.
Example:
prototype Person {
string Name = "";
Location Location = new Location();
}
prototype Location {
string Name = "";
}
prototype Homer : Person {
Name = "Homer Simpson";
Location = SimpsonsHouse;
}
prototype SimpsonsHouse : Location {
Name = "Simpsons House";
}
What’s Happening?
Homer.Locationlinks toSimpsonsHouse.- Graph View:
Homer → SimpsonsHousevia theLocationedge. - Labeled properties are intuitive, unlike OWL’s complex property declarations.
Purpose: Ensure mutual, synchronized links between Prototypes, maintaining consistency.
Syntax: Defined via paired properties or runtime synchronization.
Details:
- Properties are set to reflect mutual relationships (e.g.,
Spouselinks). - C# Analogy: Like two-way navigation properties in an ORM, with manual consistency.
Example:
prototype Person {
string Name = "";
Person Spouse = new Person();
}
prototype Homer : Person {
Name = "Homer Simpson";
Spouse = Marge;
}
prototype Marge : Person {
Name = "Marge Simpson";
Spouse = Homer;
}
What’s Happening?
Homer.Spouse = MargeandMarge.Spouse = Homercreate mutual links.- Graph View:
Homer ↔ MargeviaSpouseedges. - Bidirectional relationships are explicit and dynamic, unlike OWL’s need for inverse properties.
Purpose: Define dynamic, intensional relationships via functions, computed at runtime.
Syntax:
function Name(Parameters) : ReturnType {
// Compute relationship
}
Details:
- Functions traverse the graph to compute relationships, like dynamic queries.
- C# Analogy: Like computed properties or LINQ queries.
Example:
prototype Person {
string Name = "";
Collection ParentOf = new Collection();
function IsParent() : bool {
return ParentOf.Count > 0;
}
}
prototype Homer : Person {
Name = "Homer Simpson";
ParentOf = [Bart, Lisa, Maggie];
}
prototype Bart : Person {
Name = "Bart Simpson";
}
What’s Happening?
IsParentcomputes if aPersonhas children.Homer.IsParent()returnstrue.- Graph View: Traverses
ParentOfedges to count nodes. - Computed relationships enable flexible reasoning without OWL’s axioms.
ProtoScript’s unified graph allows relationships to span domains:
- Example: Link a
Person’sLocationto a database table’sAddresscolumn, or map a computed relationship (IsParent) to a natural language query ("Who are the parents?"). - Transformation: Convert a bidirectional
Spouserelationship to a SQL JOIN query.
Example:
prototype Query {
string Question = "";
function ToPersonList() : Collection {
Collection parents = new Collection();
if (Question == "Who are the parents?") {
foreach (Person p in AllPersons) {
if (p.IsParent()) {
parents.Add(p);
}
}
}
return parents;
}
}
What’s Happening?
- Maps a natural language question to a list of
Personnodes usingIsParent. - Unifies NLP and graph querying, unlike OWL’s separate pipelines.
Relationships are managed by ProtoScript’s runtime:
- Nodes: Prototypes are nodes with unique IDs.
- Edges: Relationships are edges (inheritance, properties, computed links).
- Runtime: Handles traversal, cycle management, and synchronization.
- Storage: Extensional relationships (e.g., properties) are stored; intensional ones (e.g., functions) are computed.
ProtoScript’s relationship taxonomy provides:
- Versatility: From simple links to complex computations, covering diverse use cases.
- Dynamic Modeling: Runtime adaptability surpasses static ontologies.
- Cross-Domain Power: Enables relationships and transformations across code, data, and language.
- Intuitive Reasoning: Structural traversal simplifies ontology queries.
This taxonomy of relationships showcases ProtoScript’s ability to model complex, dynamic connections in a graph-based ontology. In the next section, we’ll explore Shadows and Least General Generalization (LGG), diving into how ProtoScript creates ad-hoc subtypes to generalize and categorize Prototypes, further enhancing its reasoning capabilities. You’re now ready to build interconnected, flexible systems with ProtoScript!
Previous: Simpsons Example for Prototype Modeling | Next: Shadows and Least General Generalization (LGG)