Chapter 8: Populating the Clinic
The model had grown up. Dr. Portbridge now had concepts for animals, owners, vets, and appointments, with cardinality constraints, enums, and a full inheritance hierarchy. But the system was still abstract: no actual dogs, no actual owners, no actual appointments. Biscuit, the nervous golden retriever, the first patient of the morning, was sitting in the waiting room. It was time to enter some real data.
The problem
So far, your Dolfin file contains descriptions of categories: what an Animal looks like, what an Appointment requires. It contains no individuals: no specific dog named Biscuit, no actual appointment on a Tuesday afternoon. This is the gap between a schema and a database.
Dolfin fills this gap with facts.
Your first fact
fact DrPortbridge a Veterinarian
name "Helen Portbridge"
license_number "VET-2025-001"
The structure mirrors the schema:
factintroduces an instance declaration.DrPortbridgeis the instance’s identifier, you can reference it elsewhere as:DrPortbridge.a Veterinarianasserts that this instance is of typeVeterinarian.- The indented block lists property assertions, one per line: the property name, then the value.
This is the same indentation-based style you already know from concept, rule, and package declarations. No new punctuation to learn.
Primitive values
Facts support all the same primitive types you use in has declarations:
fact Biscuit a Dog
name "Biscuit"
species Dog
age 5
weight 32.4
neutered true
allergies "pollen"
| Value kind | Example |
|---|---|
| String | "Biscuit" |
| Integer | 5 |
| Float | 32.4 |
| Boolean | true |
| Enum value | Dog (no quotes) |
Enum values are written without quotes; the parser resolves them against the property’s declared type.
Referencing other facts
When a property’s type is a concept (not a primitive), the value is a reference to another fact, written with a leading colon:
fact JohnSmith a Owner
first_name "John"
last_name "Smith"
phone_numbers "555-1234"
preferred_vet :DrPortbridge
fact Biscuit a Dog
name "Biscuit"
species Dog
age 5
weight 32.4
neutered true
owner :JohnSmith
:DrPortbridge and :JohnSmith refer to the DrPortbridge and JohnSmith facts declared elsewhere in the file. Order doesn’t matter. The parser resolves identifiers after reading the whole file, so forward references work.
Anonymous blocks
Some properties hold a value that is a structured object rather than a primitive or a reference. Biscuit’s vaccination record is a good example: it’s a Vaccination instance that only belongs to Biscuit, with no need for its own global identifier.
Use an anonymous block (square brackets) for this:
fact Biscuit a Dog
name "Biscuit"
species Dog
age 5
weight 32.4
neutered true
owner :JohnSmith
vaccinations [
vaccine_name "Rabies"
date_administered "2024-03-15"
batch_number "RB-2024-0042"
]
The block’s type (Vaccination) is inferred from the property’s declared range. If the range is an abstract parent concept and you need to specify a subtype, you can add a SubType as the first line of the block:
animal [
a Dog
name "Rex"
]
Multi-valued properties
For properties with cardinality some, any, or at least N, simply repeat the property name on multiple lines:
fact JohnSmith a Owner
first_name "John"
last_name "Smith"
phone_numbers "555-1234"
phone_numbers "555-5678"
preferred_vet :DrPortbridge
Or write them as a comma-separated list:
fact JohnSmith a Owner
first_name "John"
last_name "Smith"
phone_numbers "555-1234", "555-5678"
preferred_vet :DrPortbridge
Both forms are equivalent. The first reads like structured records; the second saves space when the values are short.
Multiple anonymous blocks work the same way. Biscuit received three vaccines:
fact Biscuit a Dog
name "Biscuit"
species Dog
age 5
weight 32.4
neutered true
owner :JohnSmith
vaccinations [
vaccine_name "Rabies"
date_administered "2024-03-15"
]
vaccinations [
vaccine_name "Distemper"
date_administered "2024-03-15"
]
vaccinations [
vaccine_name "Bordetella"
date_administered "2024-03-15"
]
Multiple types
A fact can assert membership in more than one concept, separated by commas:
fact Pixel a Cat, UnvaccinatedAnimal
name "Pixel"
species Cat
indoor true
This is useful when an instance simultaneously belongs to a base concept and a flag concept. Here, Pixel is both a Cat and (currently) an UnvaccinatedAnimal. In practice, flag concepts like UnvaccinatedAnimal are usually derived by rules rather than asserted directly, but the syntax supports both.
A day at the clinic
Here are the facts for opening day at Happy Paws:
# --- Staff ---
fact DrPortbridge a Veterinarian
name "Helen Portbridge"
license_number "VET-2025-001"
fact DrReyes a Surgeon
name "Carlos Reyes"
license_number "VET-2025-042"
surgery_count 0
certified_procedures "Soft tissue"
certified_procedures "Orthopaedic"
# --- Owners ---
fact JohnSmith a Owner
first_name "John"
last_name "Smith"
phone_numbers "555-1234"
preferred_vet :DrPortbridge
# --- Animals ---
fact Biscuit a Dog
name "Biscuit"
species Dog
age 5
weight 32.4
neutered true
owner :JohnSmith
vaccinations [
vaccine_name "Rabies"
date_administered "2024-03-15"
]
vaccinations [
vaccine_name "Distemper"
date_administered "2024-03-15"
]
vaccinations [
vaccine_name "Bordetella"
date_administered "2024-03-15"
]
fact Pixel a Cat
name "Pixel"
species Cat
indoor true
# --- Appointments ---
fact Appt001 a Appointment
animal :Biscuit
date "2025-01-15"
reason "annual checkup"
urgency Routine
status Completed
diagnosis "Healthy"
treatments "Bordetella booster"
Notice:
:Biscuitin the appointment refers back to theBiscuitfact.Pixelhas noowner, she’s the stray kitten. Theoptional Ownercardinality allows this.urgency Routineandstatus Completedare enum values without quotes.
The story so far
# ============================================================
# Happy Paws: Schema + Opening Day Facts
# ============================================================
package <http://happypaws.com/clinic>:
dolfin_version "1"
version "1.0.0"
author "Dr. Helen Portbridge"
description "The Happy Paws veterinary clinic data model"
# --- Schema (chapters 1–7) ---
concept Species:
one of:
Dog
Cat
Bird
Rabbit
Reptile
Other
concept Urgency:
one of:
Routine
Urgent
Emergency
concept AppointmentStatus:
one of:
Scheduled
InProgress
Completed
Cancelled
concept Owner:
has first_name: one string
has last_name: one string
has phone_numbers: at least 1 string
has email: optional string
has address: optional string
has preferred_vet: optional Veterinarian
concept Veterinarian:
has name: one string
has license_number: one string
has specialization: optional string
concept Surgeon:
sub Veterinarian
has surgery_count: one int
has certified_procedures: at least 1 string
concept Vaccination:
has vaccine_name: one string
has date_administered: one string
has batch_number: optional string
concept Animal:
has name: one string
has species: one Species
has age: optional int
has weight: optional float
has owner: optional Owner
has vaccinations: Vaccination
has allergies: string
concept Dog:
sub Animal
has breed: optional string
has neutered: one boolean
concept Cat:
sub Animal
has indoor: one boolean
concept Appointment:
has animal: one Animal
has date: one string
has reason: one string
has urgency: one Urgency
has status: one AppointmentStatus
has diagnosis: optional string
has treatments: string
has notes: optional string
property treatedBy:
Animal -> Veterinarian
# --- Facts (chapter 8) ---
fact DrPortbridge a Veterinarian
name "Helen Portbridge"
license_number "VET-2025-001"
fact DrReyes a Surgeon
name "Carlos Reyes"
license_number "VET-2025-042"
surgery_count 0
certified_procedures "Soft tissue"
certified_procedures "Orthopaedic"
fact JohnSmith a Owner
first_name "John"
last_name "Smith"
phone_numbers "555-1234"
preferred_vet :DrPortbridge
fact Biscuit a Dog
name "Biscuit"
species Dog
age 5
weight 32.4
neutered true
owner :JohnSmith
vaccinations [
vaccine_name "Rabies"
date_administered "2024-03-15"
]
vaccinations [
vaccine_name "Distemper"
date_administered "2024-03-15"
]
vaccinations [
vaccine_name "Bordetella"
date_administered "2024-03-15"
]
fact Pixel a Cat
name "Pixel"
species Cat
indoor true
fact Appt001 a Appointment
animal :Biscuit
date "2025-01-15"
reason "annual checkup"
urgency Routine
status Completed
diagnosis "Healthy"
treatments "Bordetella booster"
Try it
Register a new patient: a rabbit named Clover, owned by Maria Garcia (phone "555-9900"). Clover is 3 years old, weighs 1.8 kg, and has had one vaccination ("RHDV2", administered "2024-11-01").
fact MariaGarcia a Owner
first_name "Maria"
last_name "Garcia"
phone_numbers "555-9900"
# Add Clover here
The system was no longer just a blueprint. It knew who worked at Happy Paws, who owned which animals, which vaccines had been given, and which appointments had been completed. Biscuit’s record showed three vaccinations and a clean checkup. Pixel’s record showed none at all.
Dr. Portbridge stared at Pixel’s entry. She was manually scanning for unvaccinated animals, overdue checkups, interns assigned to emergencies. Every check was a thing she had to remember to do. “What if the system could notice these things automatically?” she wondered. She needed the system to reason, to look at the facts and draw its own conclusions.