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., n
ew 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.