Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 2: Meet the Animals

The first patient arrived before the furniture did: a nervous-looking golden retriever named Biscuit, dragged in by an equally nervous owner. Dr. Portbridge grabbed a pen and a napkin and started writing down what she needed to know. Name? Biscuit. Owner? Some guy. Species? Dog. Age? Maybe five?

She looked at the napkin and thought: “I can do better than this.”


A concept is the core building block of any Dolfin ontology. It describes a category of things, not a specific individual, but the shape that all individuals of that kind share.

Your first concept


concept Animal:
  has name: string
  has species: string
  has age: int

This says three things:

  1. There is a concept called Animal.
  2. An Animal can have a name, which is text.
  3. An Animal can have a species (also text) and an age (a whole number).

The keyword has introduces an attribute, a piece of data that instances of this concept can carry. After has comes the attribute name, then a colon, then its type.

No constraints yet. Right now, every attribute has cardinality “any”: zero values, one value, or fifty values are all legal. That’s intentional for a first sketch, but it does mean nothing prevents an Animal with no name or three species. In a later chapter, we’ll learn how to say “exactly one name” or “at most one owner.”

Primitive types

Dolfin ships with four primitive types:

TypeWhat it holdsExamples
stringText"Biscuit", "cat"
intWhole numbers42, 0, -3
floatDecimal numbers3.14, 36.6
booleanTrue or falsetrue, false

Adding the owner

An animal doesn’t walk into a clinic alone (well, cats might). We need an owner:


concept Owner:
  has first_name: string
  has last_name: string
  has phone: string

Concepts can reference other concepts

Here’s the interesting part. An attribute’s type doesn’t have to be a primitive, it can be another concept:


concept Animal:
  has name: string
  has species: string
  has age: int
  has owner: Owner

has owner: Owner means: an Animal can be linked to an Owner. Not to a string containing the owner’s name, to the actual Owner concept, with all its attributes. This is how you build a graph of interconnected data, not just flat tables.

The story so far

Here’s what we have after this chapter:


package <http://happypaws.com/clinic>:
  dolfin_version "1"
  version "0.1.0"
  author "Dr. Helen Portbridge"
  description "The Happy Paws veterinary clinic data model"

concept Animal:
  has name: string
  has species: string
  has age: int
  has owner: Owner
  
concept Owner:
  has first_name: string
  has last_name: string
  has phone: string

Try it

Add a weight attribute (as a float) to the Animal concept:


concept Animal:
  has name: string
  has species: string
  has age: int
  has owner: Owner
  
concept Owner:
  has first_name: string
  has last_name: string
  has phone: string

Dr. Portbridge looked at the model and felt a little proud. But as she started typing in Biscuit’s details, she realized something: an appointment isn’t just an animal and an owner. It has a date, a reason, a diagnosis. The animal and the owner exist before the appointment and after it. She needed something to represent the visit itself.