130 Box of objects


namespace BOO
{
    variant Shape
    {
        { Real radius; } sphere;
        { Real radius; Real height; } cylinder;
        { Real side; } tetrahedron;
        { Real radius; Real height; } cone;
        { Real width; Real height; Real depth; } rectangular_prism;
        { Real a; Real b; Real c; } ellipsoid;
        { Real major_radius; Real minor_radius; } torus;
        { Real base_width; Real base_depth; Real height; } pyramid;
        { Real side; Real height; Real length; } triangular_prism;
        { Real radius; Real height; } capsule;
    }

    enum Element
    {
        iron, carbon, chromium, nickel, manganese,
        molybdenum, vanadium, tungsten, cobalt, copper,
        zinc, tin, lead, aluminium, magnesium, titanium,
        silicon, phosphorus, sulfur
    }

    entity Metal
    {
        { Element element; Real fraction; } component*;
    }

    enum Polymer
    {
        polyethylene, polypropylene, polystyrene, polyvinyl_chloride,
        polyethylene_terephthalate, polycarbonate, polymethyl_methacrylate,
        polyamide, polyurethane, epoxy, phenolic, silicone,
        polytetrafluoroethylene, polyetheretherketone,
        acrylonitrile_butadiene_styrene
    }

    entity PolymerBlend
    {
        { Polymer polymer; Real fraction; } component*;
    }

    variant Material
    {
        wood;
        glass;
        ceramic;
        concrete;
        Metal metal;
        PolymerBlend polymer_blend;
        { Real fiber_fraction; Real resin_fraction; } composite;
    }

    enum Color
    {
        red, green, blue, magenta, cyan, yellow
    }

    entity Object
    {
        Shape shape;
        Material material;
        Color color;
    }

    entity CountedObject
    {
        Object object;
        Integer count;
        key { object };
        constraints { count > 0; }
    }

    entity Box
    {
        CountedObject countedObject*;
    }
}


-- =========================================================
-- BOO namespace translated to Tutorial D
-- Fully relational, Information Principle compliant
-- Includes value-based uniqueness constraint for Object kinds
-- =========================================================


-- =========================================================
-- 1. Scalar types (Enums)
-- =========================================================

TYPE Element POSSREP { E CHAR };
CONSTRAINT E IN {
    'iron','carbon','chromium','nickel','manganese',
    'molybdenum','vanadium','tungsten','cobalt','copper',
    'zinc','tin','lead','aluminium','magnesium','titanium',
    'silicon','phosphorus','sulfur'
};

TYPE Polymer POSSREP { P CHAR };
CONSTRAINT P IN {
    'polyethylene','polypropylene','polystyrene','polyvinyl_chloride',
    'polyethylene_terephthalate','polycarbonate','polymethyl_methacrylate',
    'polyamide','polyurethane','epoxy','phenolic','silicone',
    'polytetrafluoroethylene','polyetheretherketone',
    'acrylonitrile_butadiene_styrene'
};

TYPE Color POSSREP { C CHAR };
CONSTRAINT C IN { 'red','green','blue','magenta','cyan','yellow' };


-- =========================================================
-- 2. Object identity (surrogate for object *kinds*)
-- =========================================================

VAR Object BASE RELATION {
    object_id INTEGER
}
KEY { object_id };


-- =========================================================
-- 3. Shape variant (10 constructors → 10 relations)
-- =========================================================

VAR Sphere BASE RELATION {
    object_id INTEGER,
    radius    REAL
}
KEY { object_id };

VAR Cylinder BASE RELATION {
    object_id INTEGER,
    radius    REAL,
    height    REAL
}
KEY { object_id };

VAR Tetrahedron BASE RELATION {
    object_id INTEGER,
    side      REAL
}
KEY { object_id };

VAR Cone BASE RELATION {
    object_id INTEGER,
    radius    REAL,
    height    REAL
}
KEY { object_id };

VAR RectangularPrism BASE RELATION {
    object_id INTEGER,
    width     REAL,
    height    REAL,
    depth     REAL
}
KEY { object_id };

VAR Ellipsoid BASE RELATION {
    object_id INTEGER,
    a         REAL,
    b         REAL,
    c         REAL
}
KEY { object_id };

VAR Torus BASE RELATION {
    object_id    INTEGER,
    major_radius REAL,
    minor_radius REAL
}
KEY { object_id };

VAR Pyramid BASE RELATION {
    object_id   INTEGER,
    base_width  REAL,
    base_depth  REAL,
    height      REAL
}
KEY { object_id };

VAR TriangularPrism BASE RELATION {
    object_id INTEGER,
    side      REAL,
    height    REAL,
    length    REAL
}
KEY { object_id };

VAR Capsule BASE RELATION {
    object_id INTEGER,
    radius    REAL,
    height    REAL
}
KEY { object_id };


-- =========================================================
-- 4. Material variant
-- =========================================================

-- Simple materials
VAR Wood BASE RELATION {
    object_id INTEGER
}
KEY { object_id };

VAR Glass BASE RELATION {
    object_id INTEGER
}
KEY { object_id };

VAR Ceramic BASE RELATION {
    object_id INTEGER
}
KEY { object_id };

VAR Concrete BASE RELATION {
    object_id INTEGER
}
KEY { object_id };

-- Metal with components
VAR MetalComponent BASE RELATION {
    object_id INTEGER,
    element   Element,
    fraction  REAL
}
KEY { object_id, element };
CONSTRAINT fraction > 0.0;

-- Polymer blend with components
VAR PolymerComponent BASE RELATION {
    object_id INTEGER,
    polymer   Polymer,
    fraction  REAL
}
KEY { object_id, polymer };
CONSTRAINT fraction > 0.0;

-- Composite material
VAR CompositeMaterial BASE RELATION {
    object_id      INTEGER,
    fiber_fraction REAL,
    resin_fraction REAL
}
KEY { object_id };


-- =========================================================
-- 5. Color
-- =========================================================

VAR ObjectColor BASE RELATION {
    object_id INTEGER,
    color    Color
}
KEY { object_id };


-- =========================================================
-- 6. Boxes and counted objects
-- =========================================================

VAR Box BASE RELATION {
    box_id INTEGER
}
KEY { box_id };

VAR BoxContents BASE RELATION {
    box_id    INTEGER,
    object_id INTEGER,
    count     INTEGER
}
KEY { box_id, object_id };
CONSTRAINT count > 0;


-- =========================================================
-- 7. Operators for value-based equality of object kinds
-- =========================================================

-- Compare shapes
OPERATOR SameShape(o1 INTEGER, o2 INTEGER) RETURNS BOOLEAN IS
    (EXISTS (Sphere WHERE object_id = o1)
         AND EXISTS (Sphere WHERE object_id = o2)
         AND ( (Sphere WHERE object_id = o1).radius =
               (Sphere WHERE object_id = o2).radius ))
 OR (EXISTS (Cylinder WHERE object_id = o1)
         AND EXISTS (Cylinder WHERE object_id = o2)
         AND ( (Cylinder WHERE object_id = o1).radius =
               (Cylinder WHERE object_id = o2).radius )
         AND ( (Cylinder WHERE object_id = o1).height =
               (Cylinder WHERE object_id = o2).height ))
 OR ...  -- similar clauses for all other shape constructors
;

-- Compare materials
OPERATOR SameMaterial(o1 INTEGER, o2 INTEGER) RETURNS BOOLEAN IS
    (EXISTS (Wood WHERE object_id = o1)
         AND EXISTS (Wood WHERE object_id = o2))
 OR (EXISTS (Glass WHERE object_id = o1)
         AND EXISTS (Glass WHERE object_id = o2))
 OR (EXISTS (Ceramic WHERE object_id = o1)
         AND EXISTS (Ceramic WHERE object_id = o2))
 OR (EXISTS (Concrete WHERE object_id = o1)
         AND EXISTS (Concrete WHERE object_id = o2))
 OR (
      -- metal comparison: same set of components
      NOT EXISTS (
        (MetalComponent WHERE object_id = o1)
        MINUS
        (MetalComponent WHERE object_id = o2)
      )
      AND
      NOT EXISTS (
        (MetalComponent WHERE object_id = o2)
        MINUS
        (MetalComponent WHERE object_id = o1)
      )
    )
 OR (
      -- polymer blend comparison
      NOT EXISTS (
        (PolymerComponent WHERE object_id = o1)
        MINUS
        (PolymerComponent WHERE object_id = o2)
      )
      AND
      NOT EXISTS (
        (PolymerComponent WHERE object_id = o2)
        MINUS
        (PolymerComponent WHERE object_id = o1)
      )
    )
 OR (
      -- composite comparison
      EXISTS (CompositeMaterial WHERE object_id = o1)
      AND EXISTS (CompositeMaterial WHERE object_id = o2)
      AND ( (CompositeMaterial WHERE object_id = o1).fiber_fraction =
            (CompositeMaterial WHERE object_id = o2).fiber_fraction )
      AND ( (CompositeMaterial WHERE object_id = o1).resin_fraction =
            (CompositeMaterial WHERE object_id = o2).resin_fraction )
    )
;

-- Compare colors
OPERATOR SameColor(o1 INTEGER, o2 INTEGER) RETURNS BOOLEAN IS
    (ObjectColor WHERE object_id = o1).color =
    (ObjectColor WHERE object_id = o2).color;


-- =========================================================
-- 8. Global constraint enforcing Predica's key { object }
-- =========================================================

CONSTRAINT NoDuplicateObjectKinds
    NOT EXISTS (
        Object AS O1 JOIN Object AS O2
        WHERE O1.object_id < O2.object_id
          AND SameShape(O1.object_id, O2.object_id)
          AND SameMaterial(O1.object_id, O2.object_id)
          AND SameColor(O1.object_id, O2.object_id)
    );