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. The first patient of the morning — Biscuit, the nervous golden retriever — 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.