#!/usr/bin/env node /** * Build Aristotle Syllogistic Logic discourse JSON and Mermaid. * Based on Prior Analytics: 4 perfect syllogisms, 3 conversion rules, 10 imperfect syllogisms. * Source: Stanford Encyclopedia of Philosophy, Aristotle's Logic. */ const fs = require('fs'); const path = require('path'); const NODES = [ { id: "DefAEIO", type: "definition", label: "A, E, I, O: All/No/Some/Some-not", short: "Categorical forms", colorClass: "definition" }, { id: "DefFig", type: "definition", label: "Three figures: middle term position", short: "Figures 1,2,3", colorClass: "definition" }, { id: "Econv", type: "axiom", label: "Eab implies Eba (No M is P implies No P is M)", short: "E-conversion", colorClass: "axiom" }, { id: "Iconv", type: "axiom", label: "Iab implies Iba (Some M is P implies Some P is M)", short: "I-conversion", colorClass: "axiom" }, { id: "Aconv", type: "axiom", label: "Aab implies Iba (All M is P implies Some P is M)", short: "A-conversion", colorClass: "axiom" }, { id: "Barbara", type: "axiom", label: "AAA-1: All M is P, All S is M therefore All S is P", short: "Barbara", colorClass: "axiom" }, { id: "Celarent", type: "axiom", label: "EAE-1: No M is P, All S is M therefore No S is P", short: "Celarent", colorClass: "axiom" }, { id: "Darii", type: "axiom", label: "AII-1: All M is P, Some S is M therefore Some S is P", short: "Darii", colorClass: "axiom" }, { id: "Ferio", type: "axiom", label: "EIO-1: No M is P, Some S is M therefore Some S is not P", short: "Ferio", colorClass: "axiom" }, { id: "Cesare", type: "theorem", label: "EAE-2: No P is M, All S is M therefore No S is P", short: "Cesare", colorClass: "theorem" }, { id: "Camestres", type: "theorem", label: "AEE-2: All P is M, No S is M therefore No S is P", short: "Camestres", colorClass: "theorem" }, { id: "Festino", type: "theorem", label: "EIO-2: No P is M, Some S is M therefore Some S is not P", short: "Festino", colorClass: "theorem" }, { id: "Baroco", type: "theorem", label: "AOO-2: All P is M, Some S is not M therefore Some S is not P", short: "Baroco", colorClass: "theorem" }, { id: "Darapti", type: "theorem", label: "AAI-3: All M is P, All M is S therefore Some S is P", short: "Darapti", colorClass: "theorem" }, { id: "Felapton", type: "theorem", label: "EAO-3: No M is P, All M is S therefore Some S is not P", short: "Felapton", colorClass: "theorem" }, { id: "Disamis", type: "theorem", label: "IAI-3: Some M is P, All M is S therefore Some S is P", short: "Disamis", colorClass: "theorem" }, { id: "Datisi", type: "theorem", label: "AII-3: All M is P, Some M is S therefore Some S is P", short: "Datisi", colorClass: "theorem" }, { id: "Bocardo", type: "theorem", label: "OAO-3: Some M is not P, All M is S therefore Some S is not P", short: "Bocardo", colorClass: "theorem" }, { id: "Ferison", type: "theorem", label: "EIO-3: No M is P, Some M is S therefore Some S is not P", short: "Ferison", colorClass: "theorem" } ]; // Dependencies (from → to). Based on Prior Analytics reduction proofs. const DEPS = { Barbara: ["DefAEIO", "DefFig"], Celarent: ["DefAEIO", "DefFig"], Darii: ["DefAEIO", "DefFig"], Ferio: ["DefAEIO", "DefFig"], Cesare: ["Econv", "Celarent"], Camestres: ["Econv", "Celarent"], Festino: ["Econv", "Ferio"], Baroco: ["Barbara"], Darapti: ["Aconv", "Darii"], Felapton: ["Aconv", "Ferio"], Disamis: ["Iconv", "Darii"], Datisi: ["Aconv", "Darii"], Bocardo: ["Barbara"], Ferison: ["Aconv", "Ferio"] }; const discourse = { schemaVersion: "1.0", discourse: { id: "aristotle-syllogistic", name: "Aristotle Syllogistic Logic", subject: "logic", variant: "classical", description: "Aristotelian categorical syllogistic. Four perfect syllogisms (Barbara, Celarent, Darii, Ferio), three conversion rules, and ten imperfect syllogisms reduced to the perfect ones. Based on Prior Analytics.", structure: { axioms: 7, definitions: 2, theorems: 10 } }, metadata: { created: "2026-03-15", lastUpdated: "2026-03-15", version: "1.0.0", license: "CC BY 4.0", authors: ["Welz, G."], methodology: "Programming Framework", citation: "Welz, G. (2026). Aristotle Syllogistic Dependency Graph. Programming Framework.", keywords: ["Aristotle", "syllogism", "categorical logic", "Prior Analytics", "Barbara", "Celarent"] }, sources: [ { id: "aristotle", type: "primary", authors: "Aristotle", title: "Prior Analytics", year: "c. 350 BCE", notes: "Syllogistic theory" }, { id: "stanford", type: "secondary", authors: "Smith, R.", title: "Aristotle's Logic", url: "https://plato.stanford.edu/entries/aristotle-logic/", notes: "Stanford Encyclopedia" } ], nodes: [], edges: [], colorScheme: { axiom: { fill: "#e74c3c", stroke: "#c0392b" }, definition: { fill: "#3498db", stroke: "#2980b9" }, theorem: { fill: "#1abc9c", stroke: "#16a085" } } }; // Add nodes for (const n of NODES) { discourse.nodes.push({ id: n.id, type: n.type, label: n.label, shortLabel: n.id, short: n.short, colorClass: n.colorClass }); for (const dep of DEPS[n.id] || []) { discourse.edges.push({ from: dep, to: n.id }); } } // Write JSON const dataDir = path.join(__dirname, "..", "data"); const outPath = path.join(dataDir, "aristotle-syllogistic.json"); fs.mkdirSync(dataDir, { recursive: true }); fs.writeFileSync(outPath, JSON.stringify(discourse, null, 2), "utf8"); console.log("Wrote", outPath); // Sanitize label for Mermaid function sanitizeMermaidLabel(s) { return String(s) .replace(/→/g, "impl") .replace(/⊢/g, "|-") .replace(/∨/g, "or") .replace(/∧/g, "and") .replace(/↔/g, "iff") .replace(/\n/g, " "); } // Generate Mermaid function toMermaid(filter) { const nodes = filter ? discourse.nodes.filter(filter) : discourse.nodes; const nodeIds = new Set(nodes.map(n => n.id)); const edges = discourse.edges.filter(e => nodeIds.has(e.from) && nodeIds.has(e.to)); const lines = ["graph TD"]; for (const n of nodes) { const desc = n.short || n.label; const raw = (n.shortLabel || n.id) + " " + (desc.length > 30 ? desc.slice(0, 27) + "..." : desc); const lbl = sanitizeMermaidLabel(raw).replace(/"/g, '\\"'); lines.push(` ${n.id}("${lbl}")`); } for (const e of edges) { lines.push(` ${e.from} --> ${e.to}`); } lines.push(" classDef axiom fill:#e74c3c,color:#fff,stroke:#c0392b"); lines.push(" classDef definition fill:#3498db,color:#fff,stroke:#2980b9"); lines.push(" classDef theorem fill:#1abc9c,color:#fff,stroke:#16a085"); const axiomIds = nodes.filter(n => n.type === "axiom").map(n => n.id).join(","); const defIds = nodes.filter(n => n.type === "definition").map(n => n.id).join(","); const thmIds = nodes.filter(n => n.type === "theorem").map(n => n.id).join(","); if (axiomIds) lines.push(` class ${axiomIds} axiom`); if (defIds) lines.push(` class ${defIds} definition`); if (thmIds) lines.push(` class ${thmIds} theorem`); return lines.join("\n"); } function closure(ids) { const needed = new Set(ids); let changed = true; while (changed) { changed = false; for (const e of discourse.edges) { if (needed.has(e.to) && !needed.has(e.from)) { needed.add(e.from); changed = true; } } } return n => needed.has(n.id); } function toMermaidWithCounts(filter) { const nodes = filter ? discourse.nodes.filter(filter) : discourse.nodes; const nodeIds = new Set(nodes.map(n => n.id)); const edges = discourse.edges.filter(e => nodeIds.has(e.from) && nodeIds.has(e.to)); return { mermaid: toMermaid(filter), nodes: nodes.length, edges: edges.length }; } // 3 sections const sections = [ { name: "foundations-perfect", ids: ["DefAEIO", "DefFig", "Econv", "Iconv", "Aconv", "Barbara", "Celarent", "Darii", "Ferio"], title: "Foundations and Perfect Syllogisms", desc: "Categorical forms, figures, conversion rules, and the four perfect syllogisms (Barbara, Celarent, Darii, Ferio)" }, { name: "figure-2", ids: ["Cesare", "Camestres", "Festino", "Baroco"], title: "Figure 2 Syllogisms", desc: "Cesare, Camestres, Festino, Baroco reduced to perfect syllogisms via conversion" }, { name: "figure-3", ids: ["Darapti", "Felapton", "Disamis", "Datisi", "Bocardo", "Ferison"], title: "Figure 3 Syllogisms", desc: "Darapti, Felapton, Disamis, Datisi, Bocardo, Ferison reduced to perfect syllogisms" } ]; const subgraphData = []; for (const s of sections) { const filter = closure(s.ids); const { mermaid: sub, nodes: n, edges: e } = toMermaidWithCounts(filter); subgraphData.push({ ...s, mermaid: sub, nodes: n, edges: e }); fs.writeFileSync(path.join(dataDir, `aristotle-syllogistic-${s.name}.mmd`), sub, "utf8"); console.log("Wrote", path.join(dataDir, `aristotle-syllogistic-${s.name}.mmd`)); } fs.writeFileSync(path.join(dataDir, "aristotle-syllogistic.mmd"), toMermaid(), "utf8"); // Generate HTML const MATH_DB = process.env.MATH_DB || "/home/gdubs/copernicus-web-public/huggingface-space/mathematics-processes-database"; const DISC_DIR = path.join(MATH_DB, "processes", "discrete_mathematics"); function htmlTemplate(title, subtitle, mermaid, nodes, edges) { const mermaidEscaped = mermaid.replace(//g, ">"); return ` ${title} - Mathematics Process

${title}

Mathematics Discrete Mathematics / Logic Source: Aristotle, Prior Analytics

Description

${subtitle}

Source: Aristotle, Prior Analytics (c. 350 BCE); Stanford Encyclopedia of Philosophy

Dependency Flowchart

Note: Arrows mean "depends on" (tail to head).

${mermaidEscaped}

Color Scheme

Red
Axioms
Blue
Definitions
Teal
Theorems

Statistics

  • Nodes: ${nodes}
  • Edges: ${edges}

Keywords

  • Aristotle
  • syllogism
  • Barbara
  • Celarent
  • Prior Analytics
  • categorical logic
`; } if (fs.existsSync(path.join(MATH_DB, "processes"))) { for (const d of subgraphData) { const html = htmlTemplate( `Aristotle Syllogistic — ${d.title}`, d.desc + ". Shows how imperfect syllogisms reduce to perfect ones via conversion.", d.mermaid, d.nodes, d.edges ); const fileName = "discrete_mathematics-aristotle-syllogistic-" + d.name; fs.writeFileSync(path.join(DISC_DIR, fileName + ".html"), html, "utf8"); console.log("Wrote", path.join(DISC_DIR, fileName + ".html")); } const indexHtml = ` Aristotle Syllogistic - Mathematics Process

Aristotle Syllogistic Logic

Categorical syllogistic from Prior Analytics. Four perfect syllogisms (Barbara, Celarent, Darii, Ferio), three conversion rules, and ten imperfect syllogisms reduced to the perfect ones. Split into three views.

Chart 1 — Foundations and Perfect Syllogisms Chart 2 — Figure 2 Syllogisms Chart 3 — Figure 3 Syllogisms
`; fs.writeFileSync(path.join(DISC_DIR, "discrete_mathematics-aristotle-syllogistic.html"), indexHtml, "utf8"); console.log("Wrote", path.join(DISC_DIR, "discrete_mathematics-aristotle-syllogistic.html")); } else { console.log("MATH_DB not found - skipping HTML generation."); } console.log("Done. Nodes:", discourse.nodes.length, "Edges:", discourse.edges.length);