Welcome to ProtoScript, a powerful, graph-based programming language developed by Matt Furnari to model and manipulate complex relationships in a flexible, dynamic way. If you’re a developer familiar with languages like C# or JavaScript, ProtoScript offers a fresh yet approachable paradigm that blends the structure of object-oriented programming with the fluidity of graph-based knowledge representation. This reference manual is your guide to mastering ProtoScript, providing clear explanations, incremental learning, and abundant examples to help you build sophisticated applications, from natural language processing to semantic transformations.
ProtoScript is a declarative, prototype-oriented language designed to work within the Buffaly system, a framework for representing knowledge as graphs. Unlike traditional programming languages that rely on rigid class hierarchies or procedural logic, ProtoScript uses Prototypes—versatile entities that act as both templates and instances—to model data and relationships as nodes and edges in a directed graph. This graph-based approach enables ProtoScript to handle diverse domains, such as:
Code Structures: Representing C# variable declarations (e.g., int i = 0) or SQL queries.
Natural Language: Parsing sentences like "I need to buy some covid-19 test kits" into semantic graphs.
Abstract Concepts: Modeling causal or conditional relationships, like "New York City is in New York State."
Think of ProtoScript as a blend of C#’s structured syntax and a database’s relational power, but with the flexibility of a graph database like Neo4j. It’s designed to simplify the creation, manipulation, and serialization of complex graph structures, making it ideal for tasks requiring dynamic categorization, transformation, and reasoning.
If you know C#, imagine ProtoScript as a language where:
Classes are replaced by Prototypes, which can inherit from multiple parents (like interfaces but more flexible) and change at runtime.
Objects are graph nodes that can represent anything—a variable, a query, or a concept—linked by edges that define relationships.
Methods are functions that traverse or modify the graph, computing results based on node connections.
For JavaScript developers, ProtoScript’s prototype-based nature might feel like JavaScript’s prototypal inheritance, but with a stronger focus on graph operations and symbolic computation rather than object cloning.
At the heart of ProtoScript lies the Prototype system, where every entity is a Prototype—a node in a graph that encapsulates properties, behaviors, and relationships. Prototypes are more than just data structures; they’re dynamic entities that can:
Inherit from Multiple Parents: A Prototype like Buffalo_City
can inherit from both City
and Location
, combining their properties without the limitations of single inheritance in C#.
Store Data: Properties like City.State = NewYork_State
represent stored (extensional) facts, similar to fields in a class.
Compute Relationships: Functions define computed (intensional) relationships, like determining if a city is in a specific state, akin to methods but operating on graph traversals.
Prototypes form a directed graph (often a directed acyclic graph, or DAG, for inheritance, with cycles allowed in property relationships), where edges represent inheritance, properties, or computed links. This structure allows ProtoScript to model complex, real-world relationships—like bidirectional links between a state and its cities—more naturally than traditional class-based systems.
Here’s a glimpse of ProtoScript modeling a city, relatable to developers familiar with object-oriented programming:
prototype City {
System.String Name = "";
State State = new State();
}
prototype NewYork_City : City {
Name = "New York City";
}
prototype State {
Collection Cities = new Collection();
}
prototype NewYork_State : State;
// Link them
NewYork_City.State = NewYork_State;
NewYork_State.Cities = [NewYork_City];
What’s Happening?
City
and State
are Prototypes, like classes but more flexible.
NewYork_City
inherits from City
, setting its Name
property.
The graph links NewYork_City
to NewYork_State
and vice versa, forming a cycle (a bidirectional relationship).
This resembles a C# class with fields but allows runtime modifications and multiple inheritance.
ProtoScript is built with several key objectives, making it a unique tool for developers:
Simplified Graph Creation: Streamline the process of building complex graph structures, reducing boilerplate compared to C#’s verbose class definitions.
Multiple Inheritance: Allow Prototypes to inherit from multiple parents, reflecting real-world complexity where entities belong to multiple categories (e.g., a Buffalo as both City
and Location
).
Support for Stored and Computed Relationships: Enable both extensional facts (e.g., City.State
) and intensional rules (e.g., a function determining valid states), akin to combining database tables with logic.
Native Graph Operations: Provide built-in tools for traversing and manipulating graphs, similar to querying a database but integrated into the language.
Serialization-First Approach: Ensure Prototypes can be easily stored or shared across systems, like JSON serialization in modern APIs.
Dynamic Runtime Modifications: Allow Prototypes to adapt at runtime, unlike C#’s static type system, enabling flexible categorization and transformation.
ProtoScript shines in scenarios requiring dynamic, interconnected data modeling, such as:
Natural Language Processing: Parsing sentences into semantic graphs for AI applications.
Code Analysis and Transformation: Refactoring code (e.g., string s1 = ""
to string s1 = string.Empty
) or generating code from NL descriptions.
Knowledge Representation: Building ontologies for domains like geography or fiction (e.g., modeling Simpsons characters).
For developers, ProtoScript offers:
Familiarity: C#-like syntax lowers the learning curve.
Power: Graph-based flexibility surpasses traditional object-oriented limitations.
Expressiveness: Dynamic features like subtyping and transformation functions enable sophisticated reasoning.
To illustrate, consider modeling characters from The Simpsons:
prototype Person {
System.String Gender = "";
Location Location = new Location();
Collection ParentOf = new Collection();
}
prototype Homer : Person {
Gender = "Male";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
}
prototype SimpsonsHouse : Location {
System.String Address = "742 Evergreen Terrace";
}
What’s Happening?
Person
defines a Prototype with properties, like a C# class.
Homer
inherits from Person
, setting specific values.
SimpsonsHouse
is a Location
node, linked to Homer
via the Location
property.
This creates a graph where Homer
connects to SimpsonsHouse
and his children, mirroring a relational database but with dynamic, graph-based querying.
This manual is structured to guide you from foundational concepts to advanced features, ensuring an incremental learning path:
Core Concepts: Learn ProtoScript’s syntax, Prototypes, and basic constructs like properties and functions, with analogies to C# and JavaScript.
Relationships: Explore the taxonomy of relationships, from simple associations to complex computed links.
Operational Constructs: Dive into shadows, hidden context prototypes, subtypes, and transformation functions for dynamic categorization and mapping.
Advanced Topics: Connect ProtoScript to graph theory, tackle complex tasks like binary addition, and explore cutting-edge ideas like dual-channel clustering.
Examples and Integration: Apply ProtoScript to practical scenarios and understand its seamless integration with C#.
Each section is packed with examples, drawing on familiar programming concepts to make ProtoScript accessible. Whether you’re building AI-driven applications or exploring symbolic computation, this manual equips you to harness ProtoScript’s full potential.
To begin, you’ll need a basic understanding of:
Object-Oriented Programming: Familiarity with classes, objects, and inheritance (e.g., in C# or Java).
Graph Concepts: A high-level grasp of nodes and edges, as in graph databases or data structures.
C# Syntax: ProtoScript’s syntax is C#-inspired, so knowledge of C# will accelerate your learning.
No prior experience with graph-based languages is required—ProtoScript’s intuitive design and this manual’s examples will guide you step-by-step. Ready to explore the graph-based world of ProtoScript? Let’s dive into the core concepts in the next section!
ProtoScript offers a dynamic, graph-based approach to building ontologies—or ontology-like systems—that prioritizes flexibility and developer intuition over the rigid, formal structures of traditional ontology frameworks. Unlike systems like OWL or RDF, which rely on static class definitions and complex logical axioms, ProtoScript uses Prototypes to represent concepts, enabling both structure and semantics to evolve at runtime. This section introduces ProtoScript’s unique position in knowledge representation, highlighting its advantages for developers building adaptive, explainable systems.
ProtoScript is a graph-based ontology representation framework built around dynamic Prototypes rather than fixed classes. It combines the flexibility of prototype-based programming with the semantic clarity of ontologies, allowing entities to inherit from multiple parents, adapt at runtime, and generate new categorizations through instance comparisons. Instead of relying solely on formal logical axioms, ProtoScript emphasizes practical, lightweight reasoning using Least General Generalizations (LGG) and subtyping operators. This makes it easier to adapt, scale, and maintain complex knowledge bases, especially in domains with evolving or uncertain conceptualizations.
For developers, ProtoScript feels like a programming language with the power of a graph database, offering a more intuitive alternative to traditional ontology systems like OWL or RDF Schema, which can be static, formal, and labor-intensive to modify.
A traditional ontology defines classes (concepts), properties (attributes/relationships), and axioms (rules for reasoning). In systems like OWL, these are static, and reasoning often requires external inference engines. ProtoScript reimagines this model in three key ways:
Prototype-Based Instead of Class-Based
Prototype-Based Instead of Class-Based
Prototypes serve as both templates and instances, unlike OWL’s static classes.
They support dynamic, multiple inheritance, eliminating the need for deep, predefined hierarchies.
Graph-Structured, Not Strictly Taxonomic
Relationships are modeled as flexible graph edges, not limited to subclassing or formal property declarations.
Prototypes can include properties, functions, and rules, supporting diverse, heterogeneous structures natively.
Reasoning Through Structural Generalization
ProtoScript uses LGG to create ad-hoc generalizations (called shadows) from instance comparisons, enabling categorization based on structural similarity.
These shadows can be stored as subtypes, providing lightweight reasoning without complex deductive rules.
Reasoning Through Structural Generalization
Traditional Ontology (OWL/RDF)
ProtoScript
Concept Definition
Static classes
Dynamic prototypes
Inheritance
Rigid, single-class hierarchies
Flexible, multiple inheritance
Runtime Adaptation
Difficult
Native support for modifying prototypes
Reasoning Model
Axioms + inference engine
Structural generalization + categorization
Transparency
High (formal semantics)
High (explicit graph structure)
Flexibility
Low
High for rapid prototyping
Best Used For
Interoperable semantic layers
Evolving, explainable knowledge graphs
Semantic Modeling with Changing Requirements: Adapt knowledge structures as new concepts emerge, without refactoring fixed hierarchies or running consistency checks.
Explainable AI and Reasoning: Trace why an instance matches a category via explicit graph paths, unlike opaque AI models.
Auditable Systems: Track prototype matches, function calls, and generalizations, ideal for domains like healthcare or finance.
Integrating External Ontologies: Import OWL or RDF schemas and evolve them with richer, dynamic behavior while preserving semantic integrity.
Consider modeling a geographic ontology:
prototype Location {
System.String Name = "";
}
prototype City : Location {
State State = new State();
}
prototype State : Location {
Collection Cities = new Collection();
}
prototype NewYork_City : City {
Name = "New York City";
}
prototype NewYork_State : State {
Name = "New York";
}
NewYork_City.State = NewYork_State;
NewYork_State.Cities = [NewYork_City];
This creates a graph where NewYork_City
and NewYork_State
form a bidirectional relationship, akin to an ontology’s object properties, but with the flexibility to add new properties or subtypes at runtime.
ProtoScript redefines ontology building with a developer-friendly, graph-based paradigm. Prototypes enable evolving knowledge structures, while built-in reasoning tools like LGG and subtyping provide transparency without heavyweight inference systems. For domains prioritizing adaptability, explainability, and real-world complexity—such as AI, regulatory systems, or messy data—ProtoScript offers a modern alternative to traditional ontologies.
Prototypes are the cornerstone of ProtoScript, serving as the fundamental units for modeling data, behavior, and relationships within the Buffaly system’s graph-based framework. If you’re familiar with C# or JavaScript, you can think of Prototypes as a hybrid of classes and objects, but with a twist: they are dynamic, graph-based entities that can act as both templates and instances, inherit from multiple parents, and adapt at runtime. This section introduces Prototypes, their key characteristics, and how they enable flexible knowledge representation, drawing analogies to familiar programming concepts and providing examples to illustrate their power.
A Prototype in ProtoScript is a node in a directed graph that encapsulates:
Properties: Stored data, like fields in a C# class, representing attributes or relationships (e.g., a city’s name or state).
Behaviors: Functions that compute results or modify the graph, similar to methods.
Relationships: Edges to other Prototypes, defining inheritance, properties, or computed links.
Unlike C# classes, which are static templates for creating objects, Prototypes blur the line between template and instance. A Prototype can be used directly (like a singleton) or instantiated to create new nodes, each inheriting its structure and behavior. This flexibility makes Prototypes ideal for modeling diverse domains, from code structures to natural language semantics.
For C# developers:
A Prototype is like a class that can also act as an object. Imagine defining a City
class with fields and methods, but you can use City
itself as an entity or create instances like NewYork_City
that inherit and extend it.
Unlike C#’s single inheritance, Prototypes support multiple parents, similar to interfaces but with richer property and behavior inheritance.
For JavaScript developers:
Prototypes resemble JavaScript’s prototypal inheritance, where objects inherit directly from other objects. However, ProtoScript Prototypes are organized in a graph, not a linear chain, and include structured properties and functions for symbolic computation.
Key Characteristics of Prototypes
Think of a Prototype as a node in a graph database (e.g., Neo4j), with properties as attributes and edges as relationships. ProtoScript adds programming logic, making these nodes programmable and dynamic.
Prototypes are designed to be versatile and expressive, with the following defining features:
Dual Role as Template and Instance
A Prototype can define a reusable structure (like a C# class) and be used directly as an entity (like an object).
Example: The City
Prototype defines properties for all cities, but City
itself
can represent a generic city in queries, or you can instantiate NewYork_City
for specific use.
can represent a generic city in queries, or you can instantiate NewYork_City
for specific use.
Multiple Inheritance
Prototypes can inherit from multiple parent Prototypes, combining their properties and behaviors without the restrictions of C#’s single inheritance.
Example: Buffalo_City
can inherit from both City
and Location
, gaining properties like State
and Coordinates
.
Stored (Extensional) Relationships
Properties store data as edges to other nodes or values, representing fixed facts, similar to database records.
Example: NewYork_City.State = NewYork_State
creates a direct link in the graph.
Computed (Intensional) Relationships
Functions define dynamic relationships or behaviors, computed at runtime by traversing or modifying the graph, akin to methods but graph-centric.
Example: A function might determine if a city is in a specific state by checking its State
property.
Dynamic Runtime Modifications
Prototypes can be modified at runtime—adding properties, changing inheritance, or updating relationships—unlike C#’s static type system.
Example: You can dynamically add a Population
property to City
during execution.
Graph-Based Structure
Prototypes form a directed graph (often a directed acyclic graph, or DAG, for inheritance, with cycles allowed in property relationships), where nodes are Prototypes and edges represent inheritance or properties.
Example: The graph links NewYork_City
to NewYork_State
and back, forming a cycle via State.Cities
.
Here’s a simple ProtoScript example to illustrate Prototypes, relatable to object-oriented programming:
prototype City {
System.String Name = "";
State State = new State();
}
prototype NewYork_City : City {
Name = "New York City";
}
prototype State {
Collection Cities = new Collection();
}
prototype NewYork_State : State {
Cities = [NewYork_City];
}
NewYork_City.State = NewYork_State;
City
is a Prototype defining a template with Name
and State
properties, like a C# class.
NewYork_City
inherits from City
, setting its Name
to "New York City."
State
defines a Cities
collection, and NewYork_State
links to NewYork_City
.
The assignment NewYork_City.State = NewYork_State
creates a bidirectional relationship, forming a cycle in the graph.
C# Equivalent: Imagine a City
class with a State
field and a State
class with a List<City>
field, but ProtoScript allows runtime modifications and multiple inheritance.
This example shows how Prototypes model real-world entities as graph nodes, with edges representing relationships, offering more flexibility than traditional classes.
In ontology terms, Prototypes are akin to classes or individuals, but with dynamic capabilities:
Classes: Like OWL classes, Prototypes define concepts (e.g., City
), but they can evolve at runtime without redefining the ontology.
Individuals: Prototypes like NewYork_City
act as instances, linked to other nodes via properties, similar to RDF triples.
Reasoning: ProtoScript uses structural generalization (e.g., comparing instances to find common patterns) rather than formal axioms, making it more adaptable for evolving knowledge bases.
For example, the City/State
graph above resembles an ontology with object properties (City.State, State.Cities
), but ProtoScript’s runtime flexibility allows adding new properties or relationships without schema changes, unlike OWL’s static structure.
To further illustrate, consider modeling characters from The Simpsons:
prototype Person {
System.String Gender = "";
Location Location = new Location();
Collection ParentOf = new Collection();
}
prototype Homer : Person {
Gender = "Male";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
}
prototype Marge : Person {
Gender = "Female";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
}
prototype SimpsonsHouse : Location {
System.String Address = "742 Evergreen Terrace";
Person is a Prototype with properties for Gender, Location, and ParentOf, like a C# class with fields.
Homer and Marge inherit from Person, setting specific values and linking to SimpsonsHouse.
SimpsonsHouse is a Location node, connected to Homer and Marge via their Location properties.
Graph View: The graph links Homer and Marge to SimpsonsHouse and their children (Bart, Lisa, Maggie), forming a network of relationships.
Database Equivalent: This resembles a relational database with tables for Person and Location, but ProtoScript’s graph allows dynamic queries and modifications.
This example demonstrates how Prototypes can model complex, interconnected entities, making them suitable for knowledge representation tasks.
Internally, Prototypes operate within a graph-based runtime:
Nodes: Each Prototype is a node with a unique identifier, storing properties and functions.
Edges: Relationships are edges, including:
Inheritance Edges: isa
links to parent Prototypes (e.g., NewYork_City isa City
).
Property Edges: Links to other nodes or values (e.g., NewYork_City.State → NewYork_State
).
Computed Edges: Functions create dynamic links at runtime.
Graph Structure: The runtime manages a directed graph, typically a DAG for inheritance, but allows cycles in property relationships (e.g., City ↔ State
).
Instantiation: Creating a new Prototype (e.g., new City()
) clones the node, copying properties and establishing new edges as needed.
This graph-centric approach enables ProtoScript to handle dynamic, real-world relationships more naturally than traditional object-oriented systems, where hierarchies are fixed and cycles are restricted to object references.
Prototypes can adapt at runtime, a feature not easily achievable in C#:
prototype Buffalo {
System.String Name = "Buffalo";
}
// Dynamically add a type
Typeofs.Insert(Buffalo, Animal);
// Add a property
prototype Color;
prototype Red : Color;
Buffalo.Properties[Color] = Red;
Buffalo
starts as a simple Prototype with a Name.
Typeofs.Insert
adds Animal
as a parent, making Buffalo typeof Animal
true.
A Color
property is dynamically added, linking Buffalo
to Red
.
C# Equivalent: This would require reflection or dynamic types, which are less straightforward and less integrated than ProtoScript’s native support.
Graph View: The runtime updates the graph, adding an isa
edge to Animal
and a property edge to Red
.
This example highlights Prototypes’ flexibility, allowing developers to evolve their models as requirements change.
Prototypes empower developers to:
Model Complex Relationships: Capture real-world complexity, like bidirectional state-city links, with ease.
Adapt Dynamically: Modify structures at runtime, ideal for evolving domains like AI or data integration.
Unify Diverse Domains: Represent code, language, or concepts in a single graph-based framework.
Enable Reasoning: Support structural generalization and categorization, as explored in later sections.
For developers, Prototypes offer a familiar yet powerful abstraction, combining the structure of classes with the flexibility of graphs, making ProtoScript a versatile tool for modern applications.
Prototypes can model programming constructs, such as a C# variable declaration:
prototype CSharp_VariableDeclaration {
CSharp_Type Type = new CSharp_Type();
System.String VariableName = "";
CSharp_Expression Initializer = new CSharp_Expression();
}
prototype CSharp_Type {
System.String TypeName = "";
}
prototype Int_Declaration : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
prototype IntegerLiteral_0 : CSharp_Expression {
System.String Value = "0";
}
CSharp_VariableDeclaration
defines a template for variable declarations, like a C# class.
Int_Declaration
represents int i = 0
, inheriting and setting specific values.
IntegerLiteral_0
models the initializer 0 as a node.
Graph View: Nodes link Int_Declaration
to CSharp_Type
(int
) and IntegerLiteral_0 (0), forming a hierarchical structure.
Use Case: This could be used for code analysis or transformation, like refactoring int i = 0
to another form.
This example shows how Prototypes unify code representation with graph-based modeling, a theme expanded in later sections.
Prototypes are the foundation of ProtoScript, providing a flexible, graph-based way to model entities and relationships. In the next section, we’ll explore ProtoScript’s syntax and features, diving into how you define, manipulate, and extend Prototypes using C#-inspired constructs. With Prototypes under your belt, you’re ready to start building dynamic, interconnected systems!
ProtoScript’s syntax and features form the backbone of its graph-based programming paradigm, enabling developers to define, manipulate, and query Prototypes within the Buffaly system. If you’re familiar with C#, ProtoScript’s syntax will feel intuitive, with a structure reminiscent of classes, methods, and attributes, but tailored for a dynamic, graph-oriented model. Unlike C#’s static, class-based approach, ProtoScript is prototype-based, allowing runtime flexibility, multiple inheritance, and graph traversal operations. This section introduces ProtoScript’s core syntax and features, providing examples to illustrate their use and drawing analogies to familiar programming concepts. We’ll cover how these elements work together to model complex relationships, with a focus on clarity for developers new to ProtoScript.
ProtoScript uses a C#-like syntax, with semicolons to terminate statements, curly braces {}
to define blocks, and comments using //
or /* */
. Its constructs are designed to create and manipulate Prototypes—graph nodes that represent entities and their relationships. Below are the key syntactic elements, each explained with comparisons to C# or JavaScript to ease the transition.
Here’s a simple ProtoScript example to set the stage:
prototype City {
System.String Name = "";
State State = new State();
}
prototype State {
Collection Cities = new Collection();
}
prototype City
defines a Prototype, like a C# class, with properties Name
and State.
prototype State
defines another Prototype with a Cities
collection.
The syntax mirrors C#’s class and field declarations but operates on graph nodes.
Comments
ProtoScript supports C#-style comments:
Single-line: // This is a comment
Multi-line: /* This is a multi-line comment */
Identifiers (e.g., Prototype names, properties, functions) follow C# conventions:
Alphanumeric with underscores, starting with a letter or underscore (e.g., City, NewYork_City, _internalState
).
Case-sensitive, like C#.
ProtoScript’s features are tailored for graph-based programming, enabling developers to define Prototypes, their properties, behaviors, and relationships. Below, we detail each feature, its syntax, and its role in the graph model, with examples to illustrate practical use.
Purpose: Defines a Prototype, the fundamental unit in ProtoScript, acting as both a template and an instance.
Syntax:
prototype Name : Parent1, Parent2 {
// Properties, functions, and other members
}
Details:
Name
is the Prototype’s identifier (e.g., City
).
: Parent1, Parent2
specifies optional parent Prototypes for multiple inheritance, like C# interfaces but inheriting properties and behaviors.
The body {}
contains properties, functions, and other members.
Unlike C# classes, Prototypes can be used directly or instantiated with new.
C# Analogy: Similar to a class
declaration, but supports multiple inheritance and runtime modification, unlike C#’s single inheritance (plus interfaces).
prototype Location {
System.String Name = "";
}
prototype City : Location {
State State = new State();
}
prototype Buffalo_City : City {
Name = "Buffalo";
}
What’s Happening?
Person
defines Gender
(a native value) and Location
(a Prototype instance).
Homer
sets Gender
to "Male" and links Location
to SimpsonsHouse.
SimpsonsHouse
has an Address
property.
Graph View: Homer
has edges to System.String[Male]
and SimpsonsHouse.
Purpose: Defines a Prototype, the fundamental unit in ProtoScript, acting as both a template and an instance.
Syntax:
function Name(Parameters) : ReturnType {
// Statements
}
Name
is the function identifier.
Parameters
are typed, like C# method parameters.
Return
Type is a Prototype or native type.
The body uses C#-like control flow (if, foreach
) and graph operations (e.g., property access, traversal).
Functions can modify the graph (e.g., setting properties) or compute values by traversing edges.
C# Analogy: Like methods, but designed for graph manipulation, often traversing or updating node relationships.
prototype City {
System.String Name = "";
State State = new State();
function GetStateName() : System.String {
return State.Name;
}
}
prototype State {
System.String Name = "";
}
prototype NewYork_City : City {
Name = "New York City";
}
prototype NewYork_State : State {
Name = "New York";
}
NewYork_City.State = NewYork_State;
City
defines a GetStateName
function that traverses the State
property to return its Name.
NewYork_City
links to NewYork_State
.
Calling NewYork_City.GetStateName()
returns "New York".
The body uses C#-like control flow (if, foreach
) and graph operations (e.g., property access, traversal).
Graph View: The function follows the State
edge to access NewYork_State.Name
.
Purpose: Attach metadata to Prototypes or functions, guiding runtime behavior, such as natural language processing or categorization.
Syntax:
[AnnotationName(Parameters)]
Details:
Annotations are applied to Prototypes or functions, similar to C# attributes.
Common annotations:
[Lexeme.SingularPlural("word", "plural")]
maps Prototypes to natural language tokens.
[SubType]
marks a Prototype for dynamic categorization (detailed in later sections).
[TransferFunction(Dimension)]
defines transformation functions (covered later).
Annotations are processed by the ProtoScript runtime, influencing interpretation or execution.
C# Analogy: Like [Attribute] in C#, but with a focus on graph behavior and runtime processing for tasks like NLP.
Example:
[Lexeme.SingularPlural("city", "cities")]
prototype City {
System.String Name = "";
}
The [Lexeme.SingularPlural
] annotation links City
to the words "city" and "cities" for natural language processing.
The runtime uses this to map text like "cities" to the City
Prototype.
Graph View: The annotation adds metadata to the City
node, used during parsing.
Purpose: Tests if a Prototype satisfies a categorization condition, querying its graph structure.
Syntax:
prototype -> Type { Condition }
Details:
prototype
is the target Prototype.
Type
specifies the context Prototype for the condition.
Condition
is a boolean expression, often involving property checks or typeof.
Returns true
if the condition holds, enabling dynamic categorization.
C# Analogy: Like a LINQ Where
clause, but operates on graph nodes and relationships rather than collections.
Example:
prototype City {
System.String Name = "";
State State = new State();
}
prototype State {
System.String Name = "";
}
prototype NewYork_City : City {
Name = "New York City";
}
prototype NewYork_State : State {
Name = "New York";
}
NewYork_City.State = NewYork_State;
function IsInNewYork(City city) : bool {
return city -> City { this.State.Name == "New York" };
}
IsInNewYork
checks if a City’s State.Name
is "New York".
NewYork_City -> City { this.State.Name == "New York" }
returns true.
Graph View: The operator traverses the State
edge to check Name.
Purpose: Checks if a Prototype inherits from another, verifying its position in the inheritance graph.
Syntax:
prototype typeof Type
Details:
Returns true if prototype has a direct or transitive isa relationship to Type.
Used in conditions, functions, or categorizations.
C# Analogy: Like the is operator in C#, but operates on the graph’s inheritance DAG.
Example:
prototype Location {
System.String Name = "";
}
prototype City : Location {
System.String Name = "";
}
prototype Buffalo_City : City {
Name = "Buffalo";
}
function IsCity(Prototype proto) : bool {
return proto typeof City;
}
What’s Happening?
IsCity(Buffalo_City)
returns true because Buffalo_City isa City.
Graph View: The operator checks for an isa edge from Buffalo_City
to City
.
Purpose: Manage lists or sets of Prototypes, representing one-to-many relationships.
Syntax:
Collection Name = new Collection();
Details:
Collection is a built-in Prototype, like List<T> in C#.
Methods include Add, Remove, and Count, similar to C# collections.
Collections are graph edges to multiple nodes.
C# Analogy: Like List<T> or IEnumerable<T>, but integrated into the graph structure.
Example:
prototype State {
Collection Cities = new Collection();
}
prototype City {
System.String Name = "";
}
prototype NewYork_State : State;
prototype NewYork_City : City {
Name = "New York City";
}
NewYork_State.Cities.Add(NewYork_City);
What’s Happening?
State.Cities
is a collection linking to City
nodes.
NewYork_State.Cities.Add(NewYork_City)
creates an edge to NewYork_City.
Graph View: NewYork_State
has a Cities edge to NewYork_City.
Purpose: Provide standard programming constructs for logic and iteration.Manage lists or sets of Prototypes, representing one-to-many relationships.
Syntax:
if (condition) {
// Statements
} else {
// Statements
}
foreach (Type variable in collection) {
// Statements
}
Details:
if
and foreach
mirror C#’s syntax and behavior.
Conditions often involve graph queries (e.g., typeof
, ->).
Used within functions to control graph operations.
C# Analogy: Nearly identical to C#’s if
and foreach
, but applied to graph nodes.
Example:
prototype State {
Collection Cities = new Collection();
function CountCities() : System.Int32 {
System.Int32 count = 0;
foreach (City city in Cities) {
count = count + 1;
}
return count;
}
}
What’s Happening?
CountCities
iterates over Cities
, counting nodes.
Graph View: The foreach
traverses Cities edges to increment count.
ProtoScript integrates seamlessly with C#:
System.String, System.Int32
, etc., mirror C# primitives, wrapped as NativeValuePrototypes.String.Format
).Example:
prototype City {
System.String Name = "";
function FormatName() : System.String {
return String.Format("City: {0}", Name);
}
}
What’s Happening?
FormatName
uses C#’s String.Format
to format the Name
property.Name
node and returns a new System.String
.ProtoScript’s syntax operates on a graph-based runtime:
isa
), properties, and computed relationships link nodes.typeof
trigger graph queries, traversing edges to evaluate conditions.ProtoScript’s syntax and features provide:
To show how these features combine, consider modeling a C# variable declaration:
prototype CSharp_VariableDeclaration {
CSharp_Type Type = new CSharp_Type();
System.String VariableName = "";
CSharp_Expression Initializer = new CSharp_Expression();
function IsInitialized() : bool {
return Initializer -> CSharp_Expression { this.Value != "" };
}
}
prototype CSharp_Type {
System.String TypeName = "";
}
prototype CSharp_Expression {
System.String Value = "";
}
prototype Int_Declaration : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
prototype IntegerLiteral_0 : CSharp_Expression {
Value = "0";
}
What’s Happening?
CSharp_VariableDeclaration
defines a Prototype with properties and a function.IsInitialized
uses the -> operator to check the Initializer’s Value
.Int_Declaration
models int i = 0
, linking to IntegerLiteral_0
.Int_Declaration
to CSharp_Type (int)
and IntegerLiteral_0 (0)
.ProtoScript’s syntax and features provide a robust foundation for graph-based programming, enabling you to define and manipulate Prototypes with ease. In the next section, we’ll explore NativeValuePrototypes, which encapsulate primitive values as graph nodes, ensuring uniformity and enabling seamless integration with the Prototype system. With these tools, you’re ready to start building dynamic, interconnected models!
In ProtoScript, NativeValuePrototypes are specialized Prototypes that encapsulate primitive values—such as strings, booleans, integers, and doubles—as nodes within the graph-based Buffaly system. For developers familiar with C# or JavaScript, NativeValuePrototypes are akin to primitive values (e.g., int
,
string
)
elevated to full-fledged graph entities, enabling them to participate in relationships, inheritance, and runtime operations like any other Prototype. This section explores the purpose, syntax, and mechanics of NativeValuePrototypes, with examples illustrating their role and analogies to familiar programming concepts.
A NativeValuePrototype is a Prototype that wraps a primitive value, such as "hello
", true
, or 42
, as a node in the graph, complete with a type identifier and metadata. Unlike raw primitives in C# (e.g., int x = 5), which lack structure, NativeValuePrototypes integrate seamlessly into ProtoScript’s graph model, allowing uniform querying, serialization, and computation. ProtoScript’s runtime translates literal values (e.g., string literals, boolean literals) into NativeValuePrototypes, making them easy to use while preserving their graph-based nature.
string, System.String
).Buffalo
" or System.String["Buffalo"]
represents the string "Buffalo" as a graph node.City
Prototype’s Name
property might be "Buffalo
", linking to a string node.string
nodes is as straightforward as querying City
nodes.false
as a property indicates a non-nullable variable.hello
".For C# developers:
object x = 5
), but as graph nodes. Using string with "hello
" is like string s = "hello"
, while System.String["hello"]
is a structured node with metadata, akin to a lightweight class.struct
types, NativeValuePrototypes are graph-integrated, not standalone.For JavaScript developers:
new String("hello")
), but persist as graph nodes, not transient wrappers, designed for traversal and relationships.For database developers:
NativeValuePrototypes are used as property values or function inputs/outputs, with ProtoScript allowing direct literal initializers ("hello", true, 42
) or explicit type notation (System.String["hello"]
). The runtime translates literals into NativeValuePrototypes, ensuring graph consistency.
Syntax Options:
Primitive Types with Literals:
string Name = "value";
bool Flag = true;
int Number = 42;
Prototype Types with Literals:
System.String Name = "value";
System.Boolean Flag = true;
System.Int32 Number = 42;
Details:
C# Analogy: Assigning string s = "hello" in C# is like string Name = "hello" in ProtoScript, but the latter creates a graph node. Using System.String["hello"] adds explicit Prototype metadata, like a structured object.
Example:
prototype City {
string Name = "";
System.Boolean IsCapital = false;
}
prototype Buffalo_City : City {
Name = "Buffalo";
IsCapital = System.Boolean[False];
}
What’s Happening?
ProtoScript supports native types aligned with C# primitives, available in two forms:
string:
Text values (e.g., "hello"
).bool:
True/false values (e.g., true
).int:
32-bit integers (e.g., 42
).double:
Floating-point numbers (e.g., 3.14
).System.String
: Text nodes (e.g., System.String["hello"]
).System.Boolean
: Boolean nodes (e.g., System.Boolean[True]
).System.Int32
: Integer nodes (e.g., System.Int32[42]
).System.Double
: Floating-point nodes (e.g., System.Double[3.14]
).Both forms are NativeValuePrototypes in the graph, with uppercase types emphasizing their node structure.
NativeValuePrototypes are crucial for ProtoScript’s graph-based model:
string
nodes finds both variable names and city names."i"
as a variable name ensures fidelity in code structures."hello"
in a function.System.Int32[0]
serializes with its type.true
flags a condition in NLP or code analysis.Representing int i = 0
:
prototype CSharp_VariableDeclaration {
CSharp_Type Type = new CSharp_Type();
string VariableName = "";
CSharp_Expression Initializer = new CSharp_Expression();
}
prototype CSharp_Type {
string TypeName = "";
bool IsNullable = false;
}
prototype CSharp_Expression {
string Value = "";
}
prototype Int_Declaration : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
prototype IntegerLiteral_0 : CSharp_Expression {
Value = "0";
}
What’s Happening?
CSharp_VariableDeclaration
uses string
for VariableName
and CSharp_Type
for Type
.Int_Declaration
sets TypeName
to "int"
, VariableName
to "i"
, and Initializer.Value
to "0
", all as NativeValuePrototypes.Int_Declaration
links to nodes for "int"
, "i"
, and "0"
.Modeling "I need to buy some covid-19 test kits":
prototype Need {
BaseObject Subject = new BaseObject();
Action Object = new Action();
}
prototype Action {
string Infinitive = "";
}
prototype COVID_TestKit {
string Quantity = "";
}
prototype Need_BuyTestKits : Need {
Subject = Person_I;
Object = BuyAction;
}
prototype Person_I : BaseObject {
System.String Pronoun = "I";
}
prototype BuyAction : Action {
Infinitive = "ToBuy";
BaseObject Object = TestKit;
}
prototype TestKit : COVID_TestKit {
Quantity = "Some";
}
What’s Happening?
string
for Infinitive
("ToBuy"
) and Quantity
("Some"
), and System.String
for Pronoun
("I"
)."I"
, "ToBuy"
, and "Some"
.NativeValuePrototypes operate within ProtoScript’s graph-based runtime:
string, System.String
) and value (e.g., "hello"
), identified by a unique ID.City.Name → "Buffalo"
).NativeValuePrototypes align with C# primitives:
string/System.String
maps to string, bool/System.Boolean
to bool
, etc. String.Format("hello")
).Example:
prototype City {
string Name = "";
function FormatName() : string {
return String.Format("City: {0}", Name);
}
}
prototype Buffalo_City : City {
Name = "Buffalo";
}
What’s Happening?
Name
uses string
with "Buffalo"
, translated to a NativeValuePrototype.FormatName
uses C#’s String.Format
."Buffalo"
node.NativeValuePrototypes ensure:
NativeValuePrototypes anchor ProtoScript’s graph model, making even simple values powerful graph entities. In the next section, we’ll explore Examples of Prototype Creation, showing how Prototypes and NativeValuePrototypes model real-world scenarios, from code to natural language semantics. You’re now equipped to build rich, interconnected systems!
ProtoScript’s Prototypes are exceptionally versatile, capable of modeling any data type—from C# code and SQL queries to database objects and natural language semantics—with the same ease and flexibility. This ability to unify diverse domains within a single graph-based framework sets ProtoScript apart from traditional ontologies, which often rely on rigid, domain-specific schemas and complex logical axioms. By representing everything as Prototypes, ProtoScript enables developers to discover relationships and transformations across domains, such as mapping a natural language request to a SQL query or transforming C# code into a semantic model. This section showcases four examples of Prototype creation, illustrating how ProtoScript handles C# variable declarations, SQL queries, database objects, and natural language, and highlights the power of cross-domain integration.
Traditional ontologies, such as those built with OWL or RDF, are designed for structured knowledge representation, typically within a single domain (e.g., medical terminology or geographic data). They use static classes, predefined properties, and formal axioms, which can be inflexible and labor-intensive to adapt across diverse data types. ProtoScript’s Prototypes overcome these limitations in several key ways:
int i = 0
) and a natural language phrase ("buy test kits") as interconnected Prototypes.prototype
construct for both a database table and a linguistic concept.For C# developers:
SqlCommand
for SQL
, string for text).For JavaScript developers:
For database developers:
Below are four examples demonstrating ProtoScript’s ability to model C# code, SQL queries, database objects, and natural language semantics, showcasing their uniform representation and cross-domain potential.
Scenario: Model the C# declaration int i = 0.
prototype CSharp_VariableDeclaration {
CSharp_Type Type = new CSharp_Type();
string VariableName = "";
CSharp_Expression Initializer = new CSharp_Expression();
}
prototype CSharp_Type {
string TypeName = "";
bool IsNullable = false;
}
prototype CSharp_Expression {
string Value = "";
}
prototype Int_Declaration : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
prototype IntegerLiteral_0 : CSharp_Expression {
Value = "0";
}
What’s Happening?
CSharp_VariableDeclaration
defines a template for variable declarations, with properties for type, name, and initializer.Int_Declaration
models int i = 0
, using string literals ("int"
, "i"
, "0"
) that the runtime translates to NativeValuePrototypes. Int_Declaration
links to nodes for "int"
, "i"
, and "0"
, forming a hierarchical structure.prototype
construct, easily adaptable to other languages (e.g., Java).Cross-Domain Potential:
TypeName
("int"
) could link to a database column’s type, enabling type consistency checks.let i: number = 0
in TypeScript).Scenario: Model the SQL query SELECT TOP 10 * FROM Prototypes ORDER BY 1 DESC.
prototype SQL_Select {
Collection Columns = new Collection();
SQL_Table Table = new SQL_Table();
string Limit = "";
Collection OrderBys = new Collection();
}
prototype SQL_Table {
string TableName = "";
}
prototype SQL_Expression {
string Value = "";
}
prototype SQL_OrderByClause {
SQL_Expression Expression = new SQL_Expression();
int SortDirection = 0; // 1 for DESC, 0 for ASC
}
prototype Select_Prototypes : SQL_Select {
Columns = [Wildcard_Expression];
Table.TableName = "Prototypes";
Limit = "10";
OrderBys = [OrderBy_FirstColumn];
}
prototype Wildcard_Expression : SQL_Expression {
Value = "*";
}
prototype OrderBy_FirstColumn : SQL_OrderByClause {
Expression = NumberLiteral_1;
SortDirection = 1;
}
prototype NumberLiteral_1 : SQL_Expression {
Value = "1";
}
What’s Happening?
SQL_Select
defines a template for SQL SELECT queries, with properties for columns, table, limit, and order-by clauses.Select_Prototypes
models the query, using literals ("Prototypes", "10", "*"
).Select_Prototypes
links to nodes for "Prototypes", "10",
and "*"
(wildcard), with OrderBys
linking to "1" and SortDirection
.Cross-Domain Potential:
TableName
("Prototypes"
) could link to a database object’s schema, ensuring consistency.Scenario: Model a database table Employees
with columns ID
(integer) and Name
(varchar).
prototype Database_Table {
string TableName = "";
Collection Columns = new Collection();
}
prototype Database_Column {
string ColumnName = "";
string DataType = "";
}
prototype Employees_Table : Database_Table {
TableName = "Employees";
Columns = [ID_Column, Name_Column];
}
prototype ID_Column : Database_Column {
ColumnName = "ID";
DataType = "int";
}
prototype Name_Column : Database_Column {
ColumnName = "Name";
DataType = "varchar";
}
What’s Happening?
Database_Table
defines a template for tables, with a name and column collection.Employees_Table
models the Employees
table, linking to ID_Column
and Name_Column.
mployees_Table
links to "Employees
" and a collection of column nodes ("ID", "int", "Name", "varchar"
).Cross-Domain Potential:
DataType
("int"
) matches the C# example’s TypeName
, enabling type alignment across code and database.Scenario: Model the sentence "I need to buy some covid-19 test kits".
prototype Need {
BaseObject Subject = new BaseObject();
Action Object = new Action();
}
prototype Action {
string Infinitive = "";
BaseObject Object = new BaseObject();
}
prototype COVID_TestKit {
string Quantity = "";
}
prototype Need_BuyTestKits : Need {
Subject = Person_I;
Object = BuyAction;
}
prototype Person_I : BaseObject {
string Pronoun = "I";
}
prototype BuyAction : Action {
Infinitive = "ToBuy";
Object = TestKit;
}
prototype TestKit : COVID_TestKit {
Quantity = "Some";
}
What’s Happening?
Need_BuyTestKits
models the sentence, with literals "I", "ToBuy",
and "Some"
as NativeValuePrototypes.Need_BuyTestKits
links to nodes for "I", "ToBuy",
and "Some"
, forming a semantic graph.Cross-Domain Potential:
Object
(TestKit
) could link to a database record for test kits, connecting language to data.SELECT * FROM TestKits WHERE Quantity = 'Some'
).ProtoScript’s unified graph model enables powerful cross-domain interactions:
"int"
in C# and database examples), allowing discovery of type consistency or semantic links (e.g., TestKit
in NLP and database).Need_BuyTestKits
could generate a SQL query by mapping TestKit
to Employees_Table’s
schema, or a C# method to fetch test kits.This flexibility surpasses traditional ontologies, which require separate models and mappings for each domain, often needing external tools for transformation.
Scenario: Transform the NLP sentence into a SQL query.
prototype QueryGenerator {
Need Need = new Need();
function ToSQL() : SQL_Select {
SQL_Select query = new SQL_Select();
if (Need.Object.Object typeof COVID_TestKit) {
query.Table.TableName = "TestKits";
query.Columns = [Wildcard_Expression];
}
return query;
}
}
prototype Wildcard_Expression : SQL_Expression {
Value = "*";
}
What’s Happening?
QueryGenerator
takes a Need Prototype (from the NLP example) and generates a SQL_Select
Prototype.Need
involves a COVID_TestKit
, setting the query’s table to "TestKits"
.Need_BuyTestKits
to a new SQL_Select
node with "TestKits"
and "*"
.SELECT * FROM TestKits
.ProtoScript’s runtime manages Prototype creation:
Int_Declaration, Select_Prototypes
) is a graph node with a unique ID."int", "Some"
).new
clones templates, and literals are translated to NativeValuePrototypes.ProtoScript’s ability to model any data type as Prototypes offers:
These examples demonstrate ProtoScript’s power to unify diverse domains in a graph, enabling cross-domain relationships and transformations that go beyond traditional ontologies. In the next section, we’ll explore the Simpsons Example for Prototype Modeling, applying these concepts to a fictional dataset to further illustrate real-world applications. You’re now ready to model and connect complex systems with ProtoScript!
ProtoScript’s Prototypes excel at modeling real-world entities and relationships within a dynamic, graph-based ontology, offering a flexible alternative to traditional ontologies like OWL or RDF. This section uses the fictional dataset from The Simpsons to demonstrate how ProtoScript creates an ontology-like structure to represent characters, locations, and their interconnections. By modeling entities such as Homer, Marge, and the Simpsons’ house as Prototypes, we illustrate how ProtoScript’s unified graph framework captures complex relationships (e.g., family ties, locations) with ease, supports runtime adaptability, and enables reasoning through structural patterns. This example highlights ProtoScript’s ability to go beyond traditional ontologies, which often rely on static schemas and formal axioms, by providing a developer-friendly, dynamic approach to knowledge representation.
The Simpsons dataset is relatable and rich with relationships, making it an ideal case study for demonstrating ProtoScript’s ontology capabilities:
Traditional ontologies define static classes (e.g., Person, Location
) and properties with formal axioms, requiring significant upfront design and external inference engines for reasoning. ProtoScript’s Prototypes offer several advantages:
prototype
construct models characters, locations, or even abstract concepts, simplifying development compared to domain-specific ontology tools.For C# developers:
For JavaScript developers:
For database developers:
This example models key characters (Homer, Marge, Bart) and locations (Simpsons’ house, Springfield) from The Simpsons, demonstrating how ProtoScript creates a graph-based ontology. We’ll define Prototypes, establish relationships, and show how the model supports querying and reasoning.
Below is the ProtoScript code to model the Simpsons ontology, corrected for syntax accuracy based on your clarifications (e.g., using lowercase string for literals, direct literal initializers).
prototype Entity {
string Name = "";
}
prototype Location : Entity {
string Address = "";
}
prototype Person : Entity {
string Gender = "";
Location Location = new Location();
Collection ParentOf = new Collection();
Person Spouse = new Person();
int Age = 0;
}
prototype SimpsonsHouse : Location {
Name = "Simpsons House";
Address = "742 Evergreen Terrace";
}
prototype Springfield : Location {
Name = "Springfield";
Address = "Unknown";
}
prototype Homer : Person {
Name = "Homer Simpson";
Gender = "Male";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = Marge;
Age = 39;
}
prototype Marge : Person {
Name = "Marge Simpson";
Gender = "Female";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = Homer;
Age = 36;
}
prototype Bart : Person {
Name = "Bart Simpson";
Gender = "Male";
Location = SimpsonsHouse;
Age = 10;
}
prototype Lisa : Person {
Name = "Lisa Simpson";
Gender = "Female";
Location = SimpsonsHouse;
Age = 8;
}
prototype Maggie : Person {
Name = "Maggie Simpson";
Gender = "Female";
Location = SimpsonsHouse;
Age = 1;
}
What’s Happening?
Entity
is a base Prototype with a Name
property, acting as a root for all entities.Location
inherits from Entity
, adding an Address
property.Person
inherits from Entity
, defining properties for Gender, Location, ParentOf, Spouse,
and Age
, using lowercase types (string, int
) with direct literals.Homer, Marge, Bart, SimpsonsHouse
) set literal values (e.g., "Male", 39
), which the runtime translates to NativeValuePrototypes.Homer.Spouse = Marge, Homer.ParentOf = [Bart, Lisa, Maggie]
).Homer, Marge
, and SimpsonsHouse
are linked via edges (Spouse, Location, ParentOf
), forming a network of relationships.Syntax Corrections:
string, bool, int
for primitive types, as per your clarification, with direct literals (e.g., "Homer Simpson", 39
).System.String[Value]
or uppercase types unless explicitly needed, aligning with examples like string Name = "Buffalo"
.Collection
is used correctly for lists (e.g., ParentOf
), matching document conventions.The Simpsons model forms a graph-based ontology:
Entity, Location, Person
act as conceptual classes, like OWL classes, but are dynamic Prototypes.Homer, Marge, SimpsonsHouse
are instances, akin to RDF individuals, linked via properties.Spouse, ParentOf, Location
are edges, similar to OWL object properties, but support runtime additions and cycles (e.g., Homer.Spouse ↔ Marge.Spouse
).Beyond Traditional Ontologies:
Occupation
, ProtoScript can dynamically add it to Person
at runtime.prototype
construct models characters and locations, unlike ontology tools needing separate class definitions.ProtoScript’s graph model supports querying relationships using functions and operators:
prototype Person {
string Gender = "";
Location Location = new Location();
Collection ParentOf = new Collection();
Person Spouse = new Person();
int Age = 0;
function IsParent() : bool {
return ParentOf.Count > 0;
}
function LivesInSpringfield() : bool {
return Location -> Location { this.Name == "Springfield" };
}
}
What’s Happening?
IsParent
checks if a Person
has children by counting ParentOf
entries.LivesInSpringfield
uses the -> operator to verify if the Location’s Name is "Springfield"
.Homer.IsParent()
returns true, Homer.LivesInSpringfield() returns true
(if SimpsonsHouse
links to Springfield
).IsParent
traverses ParentOf
edges, LivesInSpringfield
follows Location
to check Name
.The graph enables discovery of relationships:
Homer.ParentOf
and Marge.ParentOf
both link to Bart, Lisa, Maggie,
revealing shared parenthood.Person
nodes with Location = SimpsonsHouse
identifies residents (Homer, Marge, Bart, Lisa, Maggie).Homer.Spouse = Marge
and Marge.Spouse = Homer
form a bidirectional relationship, modeled naturally as a cycle.Example Function:
prototype Person {
Collection ParentOf = new Collection();
function GetChildrenNames() : Collection {
Collection names = new Collection();
foreach (Person child in ParentOf) {
names.Add(child.Name);
}
return names;
}
}
What’s Happening?
GetChildrenNames
collects Name
properties from ParentOf
nodes.Homer.GetChildrenNames()
returns a collection with "Bart Simpson", "Lisa Simpson", "Maggie Simpson"
.The Simpsons ontology can integrate with other domains:
Person
to a database table Residents
with columns Name, Gender, Age,
mapping Homer.Name
to a record.Natural Language: Transform a query like "Who lives in Springfield?" into a ProtoScript function:
prototype Query {
string Question = "";
function ToPersonList() : Collection {
Collection people = new Collection();
if (Question == "Who lives in Springfield?") {
foreach (Person p in AllPersons) {
if (p.LivesInSpringfield()) {
people.Add(p);
}
}
}
return people;
}
}
What’s Happening?:
The function maps a natural language question to a list of Person
nodes, leveraging the ontology.
Beyond Ontologies:
This transformation unifies NLP and graph querying, unlike OWL’s separate processing pipelines.
The Simpsons ontology operates within ProtoScript’s graph-based runtime:
Homer, SimpsonsHouse
) are nodes with unique IDs.Spouse, ParentOf, Location
) create edges, including cycles (e.g., Homer ↔ Marge
).Male", 39
) to NativeValuePrototypes, manages instantiation, and supports traversal.->, typeof
) traverse the graph to evaluate relationships.The Simpsons ontology showcases ProtoScript’s strengths:
This Simpsons example demonstrates how ProtoScript’s Prototypes create a dynamic, graph-based ontology that models real-world entities with ease and flexibility. In the next section, we’ll explore Relationships in ProtoScript, diving into the taxonomy of relationships—from simple associations to complex computed links—that power the ontology’s connectivity. You’re now equipped to model rich, interconnected systems with ProtoScript!
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:
Beyond Traditional Ontologies:
For C# developers:
For JavaScript developers:
For database developers:
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:
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.Members
links to Homer
and Marge
without specifying why.Springfield_Group
has edges to Homer
and Marge
nodes.Purpose: Add weight and bidirectionality to connections, forming explicit, stored relationships with minimal semantics.
Syntax:
prototype1.BidirectionalAssociate(prototype2);
Details:
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_Food
and Gravy_Food
are linked bidirectionally, with a weight of 1.Turkey_Food ↔ Gravy_Food
with weight metadata.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:
City.State → State, State.Cities → City
). 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.State
links to NewYork_State
, and NewYork_State.Cities
links back, forming a cycle.NewYork_City ↔ NewYork_State
via State
and Cities
edges.typeof
)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:
Example:
prototype Person {
string Name = "";
}
prototype Homer : Person {
Name = "Homer Simpson";
}
function IsPerson(Prototype proto) : bool {
return proto typeof Person;
}
What’s Happening?
Purpose: Represent specific, named attributes linking Prototypes, storing extensional relationships.
Syntax:
Type Name = DefaultValue;
Details:
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?
Purpose: Ensure mutual, synchronized links between Prototypes, maintaining consistency.
Syntax: Defined via paired properties or runtime synchronization.
Details:
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?
Purpose: Define dynamic, intensional relationships via functions, computed at runtime.
Syntax:
function Name(Parameters) : ReturnType {
// Compute relationship
}
Details:
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?
ProtoScript’s unified graph allows relationships to span domains:
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?
Relationships are managed by ProtoScript’s runtime:
ProtoScript’s relationship taxonomy provides:
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!
Shadows are a cornerstone of ProtoScript’s graph-based ontology, serving as the primary mechanism for learning and categorization. Through Least General Generalization (LGG), Shadows create ad-hoc subtypes that generalize common structures across Prototypes, enabling unsupervised learning without the need for gradient descent. This makes Shadows not only foundational but also revolutionary: they represent one of the only scalable, non-supervised learning mechanisms in ontology systems, distinct from traditional machine learning approaches. This section carefully unpacks Shadows and LGG, explaining their purpose, mechanics, and significance with clear analogies, step-by-step examples, and practical applications. We’ll focus on how Shadows generalize Prototypes, categorize instances, and power ProtoScript’s dynamic reasoning, ensuring clarity for developers familiar with C# or JavaScript.
Shadows are the heart of ProtoScript’s learning capability, allowing the system to:
Unique Significance:
Traditional ontologies (e.g., OWL, RDF) rely on static class definitions and formal axioms, with learning limited to predefined rules or external inference engines. ProtoScript’s Shadows offer:
For C# developers:
For JavaScript developers:
For database developers:
A Shadow is a Prototype generated by applying Least General Generalization (LGG) to two or more Prototypes, capturing their most specific common structure. It acts as an ad-hoc subtype, representing the shared properties and relationships of the input Prototypes while omitting their differences. Shadows enable ProtoScript to:
LGG Defined: LGG finds the least general (most specific) Prototype that subsumes two or more input Prototypes, retaining only their common properties, types, and relationships. It’s the opposite of finding the most specific common instance; instead, it creates the most specific shared abstraction.
Shadows are created using the compare operator, which applies LGG to two Prototypes. The process involves:
Syntax (Conceptual, executed by runtime):
Compare(prototype1, prototype2) // Returns a Shadow Prototype
C# Analogy: Like a method that compares two objects’ fields and returns a new object with only their common properties, but operating on graph nodes.
Scenario: Create a Shadow for int i = 0 and int j = -1.
Input Prototypes:
prototype CSharp_VariableDeclaration {
CSharp_Type Type = new CSharp_Type();
string VariableName = "";
CSharp_Expression Initializer = new CSharp_Expression();
}
prototype CSharp_Type {
string TypeName = "";
bool IsNullable = false;
}
prototype CSharp_Expression {
string Value = "";
}
prototype Int_Declaration_I : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
prototype IntegerLiteral_0 : CSharp_Expression {
Value = "0";
}
prototype Int_Declaration_J : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "j";
Initializer = UnaryExpression_Minus1;
}
prototype UnaryExpression_Minus1 : CSharp_Expression {
string Operator = "-";
string Value = "1";
}
Shadow Creation:
prototype InitializedIntVariable : CSharp_VariableDeclaration {
Type.TypeName = "int";
Type.IsNullable = false;
VariableName = "";
Initializer = new CSharp_Expression();
}
C# Visualization: int _ = _;
What’s Happening?
Beyond Ontologies: Unlike OWL, which requires predefined classes, Shadows dynamically learn this subtype from instance comparisons, enabling unsupervised categorization.
Scenario: Create a Shadow for Homer and Marge to identify shared traits.
Input Prototypes (from Simpsons example):
prototype Person {
string Name = "";
string Gender = "";
Location Location = new Location();
Collection ParentOf = new Collection();
Person Spouse = new Person();
int Age = 0;
}
prototype Location {
string Name = "";
}
prototype SimpsonsHouse : Location {
Name = "Simpsons House";
}
prototype Homer : Person {
Name = "Homer Simpson";
Gender = "Male";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = Marge;
Age = 39;
}
prototype Marge : Person {
Name = "Marge Simpson";
Gender = "Female";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = Homer;
Age = 36;
}
Shadow Creation:
prototype SimpsonsHouseParent : Person {
Name = "";
Gender = "";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = new Person();
Age = 0;
}
What’s Happening?
Beyond Ontologies: Shadows enable ProtoScript to learn family structures dynamically, unlike OWL’s need for predefined family classes.
Scenario: Use the Shadow to categorize a new Prototype, Ned.
New Prototype:
prototype Ned : Person {
Name = "Ned Flanders";
Gender = "Male";
Location = FlandersHouse;
ParentOf = [Rod, Todd];
Spouse = Maude;
Age = 40;
}
prototype FlandersHouse : Location {
Name = "Flanders House";
}
Categorization:
function IsSimpsonsHouseParent(Person person) : bool {
return person -> SimpsonsHouseParent {
this.Location.Name == "Simpsons House" &&
this.ParentOf.Count == 3
};
}
What’s Happening?
Beyond Ontologies: This unsupervised categorization is more flexible than OWL’s static class membership, adapting to new instances dynamically.
Shadows are generated by the ProtoScript runtime:
Scalability:
Non-Supervised Learning:
Shadows are the only learning mechanism in ProtoScript’s ontology, offering:
Beyond Gradient Descent:
Scenario: Generalize a C# variable and a database column.
Input Prototypes:
prototype Database_Column {
string ColumnName = "";
string DataType = "";
}
prototype ID_Column : Database_Column {
ColumnName = "ID";
DataType = "int";
}
Shadow Creation (with Int_Declaration_I from Example 1):
prototype IntDataElement {
string Name = "";
string Type = "int";
}
What’s Happening?
Shadows and LGG are ProtoScript’s core learning mechanism, enabling unsupervised, scalable categorization that surpasses traditional ontologies and gradient descent-based approaches. In the next section, we’ll explore Prototype Paths and Parameterization, diving into how Shadows are used to isolate differences between Prototypes, further enhancing reasoning and transformation capabilities. You’re now equipped to leverage Shadows for dynamic, interpretable learning in ProtoScript!
In ProtoScript, Prototype Paths and Parameterization extend the power of Shadows by identifying how individual Prototypes diverge from their generalized structures, enabling precise categorization, reasoning, and transformation within the graph-based ontology. Building on Shadows’ ability to create ad-hoc subtypes through Least General Generalization (LGG), Paths isolate the specific subgraphs where a Prototype differs from a Shadow, marking these differences with a Compare.Entity indicator. This process, known as Parameterization, refines ProtoScript’s unsupervised learning, allowing the system to not only generalize patterns but also pinpoint unique characteristics of individual instances. This section explains Prototype Paths and Parameterization with clarity, using step-by-step examples and analogies to familiar programming concepts, ensuring developers understand their critical role in ProtoScript’s dynamic, scalable ontology framework.
Prototype Paths and Parameterization are essential for:
Significance in ProtoScript’s Ontology:
Traditional ontologies (e.g., OWL, RDF) use static property assertions and axioms, with limited ability to dynamically analyze instance differences. ProtoScript’s Prototype Paths offer:
For C# developers:
For JavaScript developers:
For database developers:
Prototype Paths are one-dimensional navigations through a Prototype’s graph, identifying the properties or subgraphs where it diverges from a Shadow’s generalized structure. Parameterization is the process of using a Shadow to categorize a Prototype and extracting these divergent subgraphs as Paths, marked by a Compare.Entity node to indicate the point of mismatch. Together, they:
Parameterization involves:
Syntax (Conceptual, executed by runtime):
Parameterize(prototype, shadow) // Returns a set of Prototype Paths
C# Analogy: Like comparing an object to a base class and returning a dictionary of properties that differ, but operating on graph nodes and edges.
The runtime generates Paths by:
Key Indicator: Compare.Entity is a special Prototype that marks the point where the Shadow’s generalization stops, pointing to the specific subgraph (e.g., a unique value or structure).
Scenario: Parameterize int i = 0 against its Shadow from the previous section.
Shadow (from int i = 0 and int j = -1):
prototype InitializedIntVariable : CSharp_VariableDeclaration {
Type.TypeName = "int";
Type.IsNullable = false;
VariableName = "";
Initializer = new CSharp_Expression();
}
Input Prototype:
prototype CSharp_VariableDeclaration {
CSharp_Type Type = new CSharp_Type();
string VariableName = "";
CSharp_Expression Initializer = new CSharp_Expression();
}
prototype CSharp_Type {
string TypeName = "";
bool IsNullable = false;
}
prototype CSharp_Expression {
string Value = "";
}
prototype Int_Declaration_I : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
prototype IntegerLiteral_0 : CSharp_Expression {
Value = "0";
}
Parameterization:
Int_Declaration_I.VariableName = Compare.Entity
// Result: string["i"]
Path 2: Initializer
// Result: IntegerLiteral_0 { Value = "0" }
What’s Happening?
Beyond Ontologies: Unlike OWL’s static property assertions, Paths dynamically identify instance-specific differences, enabling flexible reasoning without predefined rules.
Scenario: Parameterize Homer against the SimpsonsHouseParent Shadow.
Shadow (from Homer and Marge):
prototype SimpsonsHouseParent : Person {
Name = "";
Gender = "";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = new Person();
Age = 0;
}
Input Prototype:
prototype Person {
string Name = "";
string Gender = "";
Location Location = new Location();
Collection ParentOf = new Collection();
Person Spouse = new Person();
int Age = 0;
}
prototype Location {
string Name = "";
}
prototype SimpsonsHouse : Location {
Name = "Simpsons House";
}
prototype Homer : Person {
Name = "Homer Simpson";
Gender = "Male";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = Marge;
Age = 39;
}
prototype Marge : Person {
Name = "Marge Simpson";
}
Parameterization:
Path 1: Name
Homer.Name = Compare.Entity
// Result: string["Homer Simpson"]
Path 2: Gender
Homer.Gender = Compare.Entity
// Result: string["Male"]
Path 3: Spouse
Homer.Spouse = Compare.Entity
// Result: Marge
Path 4: Age
Homer.Age = Compare.Entity
// Result: int[39]
What’s Happening?
Beyond Ontologies: Paths provide a granular view of instance differences, enabling dynamic reasoning without OWL’s complex SPARQL queries.
Scenario: Use Paths to transform a C# variable to a database column.
Shadow (from Int_Declaration_I and ID_Column, previous section):
prototype IntDataElement {
string Name = "";
string Type = "int";
}
Input Prototype:
prototype Int_Declaration_I : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
Parameterization:
Paths:
Path 1: Name
Int_Declaration_I.VariableName = Compare.Entity
// Result: string["i"]
Path 2: Initializer
Int_Declaration_I.Initializer = Compare.Entity
// Result: IntegerLiteral_0 { Value = "0" }
Transformation:
prototype Database_Column {
string ColumnName = "";
string DataType = "";
}
function ToDatabaseColumn(CSharp_VariableDeclaration var) : Database_Column {
Database_Column col = new Database_Column();
col.DataType = var.Type.TypeName;
Parameterize(var, IntDataElement);
col.ColumnName = var.VariableName; // From Path 1
return col;
}
What’s Happening?
The ProtoScript runtime manages Parameterization:
Scalability:
Prototype Paths and Parameterization:
Beyond Gradient Descent: Paths refine Shadows’ learning without iterative optimization, offering a deterministic, scalable alternative for ontology reasoning.
Prototype Paths and Parameterization refine ProtoScript’s unsupervised learning, isolating instance-specific details to enhance categorization and transformation.
Subtypes in ProtoScript are a powerful feature that enables dynamic reclassification of Prototypes at runtime, allowing them to adopt more specific types based on context-sensitive conditions. Unlike traditional ontologies, which rely on static class hierarchies, Subtypes use runtime-evaluated functions to categorize Prototypes, making ProtoScript’s graph-based ontology exceptionally adaptive and flexible. Building on Shadows and Prototype Paths, Subtypes refine ProtoScript’s unsupervised learning by creating precise, ad-hoc categories that evolve with the data. This section explains Subtypes, their syntax, mechanics, and significance, using clear analogies, step-by-step examples, and practical applications to ensure developers familiar with C# or JavaScript can grasp their role in dynamic ontology reasoning.
Subtypes are a cornerstone of ProtoScript’s dynamic ontology, enabling:
Significance in ProtoScript’s Ontology:
Traditional ontologies (e.g., OWL, RDF) use static class definitions and axioms, requiring upfront design and external inference engines for categorization. ProtoScript’s Subtypes offer:
For C# developers:
For JavaScript developers:
For database developers:
A Subtype in ProtoScript is a Prototype that defines a dynamic category, applied to other Prototypes at runtime if they satisfy a categorization function. Unlike static inheritance (e.g., prototype Child : Parent), Subtypes are evaluated dynamically using the IsCategorized function, which checks properties and relationships via the -> operator. Subtypes:
Subtypes are defined with the [SubType] annotation and an IsCategorized function, executed by the runtime to determine membership:
Syntax:
[SubType]
prototype SubtypeName : Parent {
function IsCategorized(Parent proto) : bool {
return proto -> Parent { /* Conditions */ };
}
}
C# Analogy: Like defining a dynamic interface with a method to check if an object qualifies, but integrated into the graph and applied at runtime.
Scenario: Define a Subtype for “initialized integer variables” and apply it to int i = 0.
Shadow Reference (from previous section):
prototype InitializedIntVariable : CSharp_VariableDeclaration {
Type.TypeName = "int";
Type.IsNullable = false;
VariableName = "";
Initializer = new CSharp_Expression();
}
Subtype Definition:
prototype CSharp_VariableDeclaration {
CSharp_Type Type = new CSharp_Type();
string VariableName = "";
CSharp_Expression Initializer = new CSharp_Expression();
}
prototype CSharp_Type {
string TypeName = "";
bool IsNullable = false;
}
prototype CSharp_Expression {
string Value = "";
}
[SubType]
prototype InitializedIntVariable_SubType : CSharp_VariableDeclaration {
function IsCategorized(CSharp_VariableDeclaration var) : bool {
return var -> CSharp_VariableDeclaration {
this.Type.TypeName == "int" &&
this.Type.IsNullable == false &&
this.Initializer != new CSharp_Expression()
};
}
}
Application:
prototype Int_Declaration_I : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
prototype IntegerLiteral_0 : CSharp_Expression {
Value = "0";
}
UnderstandUtil.SubType(Int_Declaration_I, _interpreter);
What’s Happening?
Beyond Ontologies: Unlike OWL’s static class membership, Subtypes dynamically reclassify Prototypes, leveraging Shadows for unsupervised categorization.
Scenario: Define a Subtype for “parents in the Simpsons’ house” and apply it to Homer.
Shadow Reference (SimpsonsHouseParent):
prototype SimpsonsHouseParent : Person {
Name = "";
Gender = "";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = new Person();
Age = 0;
}
Subtype Definition:
prototype Person {
string Name = "";
string Gender = "";
Location Location = new Location();
Collection ParentOf = new Collection();
Person Spouse = new Person();
int Age = 0;
}
prototype Location {
string Name = "";
}
prototype SimpsonsHouse : Location {
Name = "Simpsons House";
}
[SubType]
prototype SimpsonsHouseParent_SubType : Person {
function IsCategorized(Person person) : bool {
return person -> Person {
this.Location.Name == "Simpsons House" &&
this.ParentOf.Count > 0
};
}
}
Application:
prototype Homer : Person {
Name = "Homer Simpson";
Gender = "Male";
Location = SimpsonsHouse;
ParentOf = [Bart, Lisa, Maggie];
Spouse = Marge;
Age = 39;
}
prototype Marge : Person {
Name = "Marge Simpson";
}
UnderstandUtil.SubType(Homer, _interpreter);
What’s Happening?
Beyond Ontologies: Subtypes enable context-sensitive categorization, adapting to runtime data unlike OWL’s predefined classes.
Scenario: Define a Subtype for “integer data elements” across C# variables and database columns.
Shadow Reference (IntDataElement):
prototype IntDataElement {
string Name = "";
string Type = "int";
}
Subtype Definition:
prototype DataElement {
string Name = "";
string Type = "";
}
[SubType]
prototype IntDataElement_SubType : DataElement {
function IsCategorized(DataElement elem) : bool {
return elem -> DataElement {
this.Type == "int"
};
}
}
Application:
prototype CSharp_VariableDeclaration : DataElement {
string Name = "";
string Type = "";
}
prototype Database_Column : DataElement {
string Name = "";
string Type = "";
}
prototype Int_Declaration_I : CSharp_VariableDeclaration {
Name = "i";
Type = "int";
}
prototype ID_Column : Database_Column {
Name = "ID";
Type = "int";
}
UnderstandUtil.SubType(Int_Declaration_I, _interpreter);
UnderstandUtil.SubType(ID_Column, _interpreter);
What’s Happening?
Beyond Ontologies: Subtypes unify code and database domains dynamically, unlike OWL’s separate ontologies.
Subtypes build on prior learning mechanisms:
The ProtoScript runtime manages Subtypes:
Subtypes:
Beyond Gradient Descent: Subtypes offer a deterministic, unsupervised alternative, leveraging graph structures for scalability and clarity.
Subtypes empower ProtoScript’s ontology with dynamic, context-sensitive categorization, building on Shadows and Paths to create a robust unsupervised learning framework.
Transformation Functions in ProtoScript are runtime-driven operations that map one Prototype to another, enabling seamless transformations across diverse domains, such as converting a natural language (NL) statement to C# code or a database query to a semantic model. Unlike traditional ontology systems, which rely on static mappings or external tools, Transformation Functions operate within ProtoScript’s graph-based framework, leveraging Shadows, Prototype Paths, and Subtypes to dynamically transform Prototypes based on their structure and context. This section explains the purpose, syntax, mechanics, and significance of Transformation Functions, using clear analogies, step-by-step examples, and practical applications to ensure developers familiar with C# or JavaScript can harness their power for adaptive, cross-domain reasoning.
Transformation Functions are a key component of ProtoScript’s ontology, enabling:
Significance in ProtoScript’s Ontology:
Traditional ontologies (e.g., OWL, RDF) use static property assertions and external mapping tools, limiting their ability to dynamically transform data across domains. ProtoScript’s Transformation Functions offer:
For C# developers:
For JavaScript developers:
For database developers:
A Transformation Function is a ProtoScript function marked with the [TransferFunction] annotation, executed by the runtime to map an input Prototype to an output Prototype of a different type. Unlike regular functions, Transformation Functions are invoked automatically by the runtime based on a specified dimension (e.g., NL, Implication), forming a computational graph of transformations. They:
Transformation Functions are defined with a specific syntax and executed by the runtime in a hierarchical, recursive process:
Syntax:
[TransferFunction(Dimension)]
function FunctionName(InputType input) : OutputType {
// Construct and return new Prototype
}
C# Analogy: Like a factory method with dependency injection, where the runtime selects and chains methods based on attributes, but operating on graph nodes.
Scenario: Transform the NL statement “the lady whispered” to a semantic VerbalCommunication Prototype.
Input Prototype:
prototype WhisperBase {
BaseObject Subject = new BaseObject();
string Action = "";
}
prototype Person {
string Name = "";
}
prototype Whisper_Lady : WhisperBase {
Subject = Lady;
Action = "Whisper";
}
prototype Lady : Person {
Name = "Lady";
}
Transformation Function:
prototype VerbalCommunication {
BaseObject SourceActor = new BaseObject();
string Volume = "";
}
prototype Quietly {
string Level = "Quiet";
}
[TransferFunction(NL)]
function Whisper_To_VerbalCommunication_1(WhisperBase action) : VerbalCommunication {
VerbalCommunication meaning = new VerbalCommunication();
if (action.Subject != new BaseObject()) {
meaning.SourceActor = action.Subject;
}
meaning.Volume = Quietly.Level;
return meaning;
}
Application:
Collection sememes = UnderstandUtil.TransferToSememesWithDimension(Whisper_Lady, NL, _interpreter);
What’s Happening?
Beyond Ontologies: Unlike OWL’s static mappings, Transformation Functions dynamically convert NL to semantics, leveraging the graph for flexibility.
Scenario: Transform int i = 0 to a database column.
Input Prototype (from prior sections):
prototype CSharp_VariableDeclaration {
CSharp_Type Type = new CSharp_Type();
string VariableName = "";
CSharp_Expression Initializer = new CSharp_Expression();
}
prototype CSharp_Type {
string TypeName = "";
bool IsNullable = false;
}
prototype Int_Declaration_I : CSharp_VariableDeclaration {
Type.TypeName = "int";
VariableName = "i";
Initializer = IntegerLiteral_0;
}
prototype IntegerLiteral_0 : CSharp_Expression {
string Value = "0";
}
Transformation Function:
prototype Database_Column {
string ColumnName = "";
string DataType = "";
}
[TransferFunction(Database)]
function Variable_To_Column(CSharp_VariableDeclaration var) : Database_Column {
Database_Column col = new Database_Column();
col.DataType = var.Type.TypeName;
col.ColumnName = var.VariableName;
return col;
}
Application:
Collection columns = UnderstandUtil.TransferToSememesWithDimension(Int_Declaration_I, Database, _interpreter);
What’s Happening?
Beyond Ontologies: Transformation Functions unify code and database domains, unlike OWL’s need for separate ontologies.
Scenario: Transform an NL question “Who lives in Springfield?” to a list of Person Prototypes, using hierarchical dimensions.
Input Prototype:
prototype Query {
string Question = "";
}
prototype Springfield_Query : Query {
Question = "Who lives in Springfield?";
}
Transformation Functions:
prototype Person {
string Name = "";
Location Location = new Location();
}
prototype Location {
string Name = "";
}
prototype SimpsonsHouse : Location {
Name = "Simpsons House";
}
prototype Homer : Person {
Name = "Homer Simpson";
Location = SimpsonsHouse;
}
[TransferFunction(NL)]
function Query_To_PersonList(Query query) : Collection {
Collection people = new Collection();
if (query.Question == "Who lives in Springfield?") {
foreach (Person p in AllPersons) {
if (p.Location.Name == "Simpsons House") {
people.Add(p);
}
}
}
return people;
}
[TransferFunction(NL.Informative)]
function Query_To_InformativeList(Query query) : Collection {
// Subset of NL, for informative queries
return Query_To_PersonList(query);
}
Application:
Collection people = UnderstandUtil.TransferToSememesWithDimension(Springfield_Query, NL, _interpreter);
What’s Happening?
Beyond Ontologies: Hierarchical dimensions enable flexible, runtime-driven transformations, unlike OWL’s static query pipelines.
Transformation Functions build on prior learning mechanisms:
The ProtoScript runtime manages Transformation Functions:
Transformation Functions:
Beyond Gradient Descent: Transformation Functions offer a deterministic, unsupervised alternative, leveraging graph structures for scalability and clarity.
Transformation Functions empower ProtoScript’s ontology with dynamic, cross-domain mappings, building on its unsupervised learning framework to automate complex tasks.