Representing objects

Composing abstractions

Introduction

AWMT is a tool that allows both humans and AI agents to create and manipulate abstractions either with a structured GraphQL API or through language.

The fundamental entity used for representing abstraction is called a model. A model is the representation of the structure, properties, values, constraints, and relationships of an abstraction. A model can be used to represent anything from a simple value to a complex system.

A model can be compared to a small packet of neuron in your brain that represent a specific concept or object. The model can be connected to other models to form a network of interconnected ideas.

AWMT provides a set of API methods to create, manipulate, and query models. The API methods are designed to be simple and intuitive.

Models

Creating a model

Each model is designated by its path. The path is a unique identifier for the model. The path is used to refer to the model in the API methods.

Each model can also have a label and a description. The label is a human-readable name for the model. The description is a human-readable description of the model.

Later, when we will search for models, the label and description will be used to match the existing models with the search query.

request.gql
mutation {
	User: create_model(label: "User") {
		model {
			path
			label
		}
	}
 
	Car: create_model(label: "Car") {
		model {
			path
			label
		}
	}
}
response.json
{
  "data": {
    "User": {
      "model": {
        "path": "user",
        "label": "User"
      }
    },
    "Car": {
      "model": {
        "path": "car",
        "label": "Car"
      }
    }
  }
}

Inheritance

The most basic operation in model composition is inheritance. Inheritance allows you to create a new model that inherits the properties of an existing model.

This can represent two distinct situations : prototype/instance, and superclass/subclass.

A model is an instance of another model if it represents the implementation of the abstraction defined by the other model. For example, "my car" is an instance of the model "car", and "car" is a prototype of "my car".

A model is a subclass of another model if it represents a specialization of the abstraction defined by the other model. For example, "ferrari car" is a subclass of "car" because it is a specialized type of car.

If a model is an instance or a subclass of another model, it inherits all the properties of the other model, and is able to complete them or add new ones.

request.gql
mutation {
	at(path: "car") {
		instantiate(label: "my car") {
			model {
				# returns the model "my car"
				path
				label
 
				prototypes {
					# returns the prototypes of "my car", so, in this case, "car"
					path
					label
				}
			}
		}
	}
}
response.json
{
  "data": {
    "at": {
      "instantiate": {
        "model": {
          "path": "mkwh4q2cjr9rr_y8c", # the path is generated by the system
          "label": "my car",
          "prototypes": [
            {
              "path": "car",
              "label": "Car"
            }
          ]
        }
      }
    }
  }
}
request.gql
mutation {
	at(path: "car") {
		extend(label: "ferrari car") {
			model {
				# returns the model "ferrari car"
				path
				label
 
				superclasses {
					# returns the superclasses of "ferrari car", so, in this case, "car"
					path
					label
				}
			}
		}
	}
}
response.json
{
  "data": {
    "at": {
      "extend": {
        "model": {
          "path": "ferrari_car",
          "label": "ferrari car",
          "superclasses": [
            {
              "path": "car",
              "label": "Car"
            }
          ]
        }
      }
    }
  }
}

Removing a model

A model can be removed by its path.

request.gql
mutation {
	at(path: "ferrari_car") {
		remove_model # removes the model "ferrari_car"
	}
}

Getting a model

A model can be retreived by two ways: directly by its path, or by making a search query. In the case of a search query, the abstraction layer will return the list of models that are the closest match to the search query based on their labels and descriptions, along with a score that indicates how well they match the search query.

request.gql
query {
	model(path: "user_12345") {
		# returns the model "user_12345"
		path
		label
		description
	}
}
request.gql
query {
	search_models(query: "a person who signed up to the site") {
		model {
			path
			label
		}
		score
	}
}

Labels and descriptions

request.gql
mutation {
	at(path: "my_car") {
		set_label(label: "My car") {
			model {
				label
			}
		}
		set_description(description: "This is my car") {
			model {
				description
			}
		}
	}
}

Submodels

Submodels are the second important idea in model composition. A submodel is a model that is part of another model. A submodel can be used to represent a part-whole relationship between two abstractions.

For instance "car" can have submodels like "doors", "engine", "manufacturer", etc.

"User" can have submodels like "name", "email", "password", etc.

They can either represent properties, relationships, parts, components of their parent model.

Submodels are considered as models, so everything applied to models can be applied to submodels. They can have inheritance (for instance, "car:door" may be an instance of "number"), submodels, labels, descriptions, etc.

request.gql
mutation {
	at(path: "car") {
		doors: create_submodel(subpath: "doors", label: "Doors") {
			model {
				path
				label
			}
		}
 
		manufacturer: create_submodel(subpath: "manufacturer", label: "Manufacturer") {
			model {
				path
				label
			}
		}
	}
}
request.gql
query {
	model(path: "car") {
		at(submodel: "doors") {
			number_value
		}
 
		number_value(path: "doors")
 
		manufacturer: at(submodel: "manufacturer") {
			path
			label
		}
	}
}

The submodels are themselved passed to instances and subclasses. So if car has a "manufacturer" submodel, "ferrari car" will automatically have a "manufacturer" submodel, and the submodel of "ferrari car" can be completed to contain a reference to the "ferrari" company model.

request.gql
mutation { # We create the ferrari company
	at(path: "company") {
		instantiate(label: "Ferrari") {
			model {
				label
			}
		}
	}
}
 
mutation { # In the car model, we create the manufacturer submodel
	at(path: "car") {
		create_submodel(subpath: "manufacturer", label: "Manufacturer") {
			model {
				path
				label
			}
		}
	}
}
 
mutation { # We create the ferrari_car subclass
	at(path: "car") {
		instantiate(label: "Ferrari Car") {
			model {
				label
			}
		}
	}
}
 
mutation { # We get the ferrari_car subclass, which interit the manufacturer submodel from the car model, and we complete it with a reference to the ferrari company
	at(path: "ferrari_car") {
		at(submodel: "manufacturer") {
			set_reference(reference: "ferrari") {
				model {
					label
				}
			}
		}
	}
}

References

A submodel can be a reference to another model. This is useful when the submodel is a relationship to another model.

For instance, a "car" can have a "manufacturer" submodel that is a reference to a "company" model.

request.gql
mutation {
	at(path: "car") {
		create_submodel(subpath: "manufacturer", label: "Manufacturer") {
			model {
				path
				label
			}
		}
	}
}
 
mutation {
	at(path: "car") {
		instantiate(label: "My Car") {
			at(submodel: "manufacturer") {
				set_reference(reference: "peugeot") {
					model {
						label
					}
				}
			}
		}
	}
}

Validation