# 02 · 本体建模实现

> 目标：基于解析出的表结构，用 OWL 2 建指标本体（指标类、维度类、口径公理），产出可被推理引擎加载的 Turtle 文件。

## 1. 建模工具

- **Protégé**（可视化建模）或直接手写 **Turtle（.ttl）**
- 命名空间：`http://example.org/metric-ontology#`

## 2. 概念类 + 关系（TBox）

```turtle
@prefix : <http://example.org/metric-ontology#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

# ===== 指标类 =====
:Metric a owl:Class .
:AtomicMetric   a owl:Class ; rdfs:subClassOf :Metric .
:DerivedMetric  a owl:Class ; rdfs:subClassOf :Metric .
:CompositeMetric a owl:Class ; rdfs:subClassOf :Metric .

# ===== 维度类 =====
:Dimension a owl:Class .
:RegionDimension a owl:Class ; rdfs:subClassOf :Dimension .
:TimeDimension a owl:Class ; rdfs:subClassOf :Dimension .

# ===== 关系 =====
:mapsToColumn a owl:DatatypeProperty .   # 映射到物理字段
:composedOf a owl:ObjectProperty .       # 复合指标组成
:derivedFrom a owl:ObjectProperty .      # 派生指标来源
:partOf a owl:ObjectProperty, owl:TransitiveProperty .  # 维度层级（传递）
:equivalentTo a owl:ObjectProperty, owl:SymmetricProperty, owl:TransitiveProperty .
```

## 3. 指标实例 + 口径公理（ABox，映射到现有表）

```turtle
# ===== 指标实例：基于账单表字段 =====
# 成交额（GMV）：原子指标，映射到账单表的 bill_amount
:GMV a :AtomicMetric ;
    :mapsToColumn "dwd_bill.bill_amount" ;
    :calcExpression "SUM(bill_amount)" ;
    :whereClause "status='paid' AND refunded=false" .   # ← 口径公理

# 订单数：原子指标，映射到 bill_count
:订单数 a :AtomicMetric ;
    :mapsToColumn "dwd_bill.bill_count" ;
    :calcExpression "SUM(bill_count)" ;
    :whereClause "status='paid'" .

# ===== 等价公理（业务术语对齐）=====
:成交额 a :AtomicMetric ; owl:equivalentClass :GMV .
:销售额 a :AtomicMetric ; owl:equivalentClass :GMV .

# ===== 指标推导公理 =====
:客单价 a :CompositeMetric ;
    :composedOf :GMV, :订单数 .

# ===== 维度层级公理（基于 dim_region.region_group）=====
:上海 :partOf :华东区 .  :江苏 :partOf :华东区 .  :浙江 :partOf :华东区 .
:安徽 :partOf :华东区 .  :福建 :partOf :华东区 .  :江西 :partOf :华东区 .
:山东 :partOf :华东区 .  :华东区 :partOf :中国 .
```

## 4. 关键：口径用公理固化

口径公理是本体的核心价值——把「GMV 不含退款」从文档文字变成机器可读的公理：

```turtle
:GMV :whereClause "status='paid' AND refunded=false" .
```

这个公理在 05 受约束 SQL 生成时被读取，强制拼进 SQL 的 WHERE 条件，从机制上保证口径一致。

## 5. 验证推理

```bash
# 验证等价推理：查询与 GMV 等价的指标
sparql --data metric.ttl --query "SELECT ?m WHERE { ?m owl:equivalentClass :GMV }"
# 期望：成交额、销售额

# 验证层级展开：查询华东区包含的地区
sparql --data metric.ttl --query "SELECT ?r WHERE { ?r :partOf :华东区 }"
# 期望：上海、江苏、浙江、安徽、福建、江西、山东（传递性自动展开）
```

## 6. 关键注意

- **映射直接指向现有表字段**（`dwd_bill.bill_amount`），不做数仓改造
- **口径公理要精确**：`whereClause` 就是指标的 SQL 过滤条件，必须与业务口径严格一致
- **等价关系用 `owl:equivalentClass`**：这是推理机识别"成交额=GMV"的关键
- **层级关系设 `Transitive`**：传递性让推理机自动推出"上海 partOf 中国"，不用穷举
- **MVP 精而少**：3 个指标 + 1 个维度层级 + 2 个等价关系，先验证闭环
