denotational-semantics-builder
Skill17 starsChanged 9 months agoApache-2.0View on GitHub
Builds denotational semantic models. Use when: (1) Formalizing language
In this repository98 other files it gives its agents.
- abstract-interpretation-engineSkill
- abstract-machineSkill
- acsl-annotation-assistantSkill
- actor-model-implementerSkill
- algebraic-effectsSkill
- alias-and-points-to-analysisSkill
- axiomatic-semanticsSkill
- bidirectional-type-checkingSkill
- bisimulation-checkerSkill
- capability-systemSkill
- closure-converterSkill
- common-subexpression-eliminatorSkill
- concurrency-verifierSkill
- constant-propagation-passSkill
- contextual-equivalenceSkill
- control-flow-analysisSkill
- coq-proof-assistantSkill
- cps-transformerSkill
- dafny-verifierSkill
- dataflow-analysis-frameworkSkill
- dead-code-eliminatorSkill
- defunctionalizationSkill
- dependent-type-implementerSkill
- dsl-embeddingSkill
- effect-handlers-implementerSkill
- effect-systemSkill
- effect-type-systemSkill
- escape-analysisSkill
- existential-typesSkill
- ffi-designerSkill
- fuzzer-generatorSkill
- gadt-implementerSkill
- garbage-collector-implementerSkill
- graalvm-truffle-implementerSkill
- gradual-typing-implementerSkill
- higher-order-abstract-syntaxSkill
- hoare-logic-verifierSkill
- incremental-computationSkill
- information-flow-analyzerSkill
- inline-expanderSkill
- interprocedural-analysisSkill
- invariant-generatorSkill
- jit-compiler-builderSkill
- lambda-calculus-interpreterSkill
- language-server-protocolSkill
- lean-proverSkill
- lexer-generatorSkill
- linear-type-implementerSkill
- liveness-analysisSkill
- llvm-backend-generatorSkill
- lock-free-data-structureSkill
- loop-optimizerSkill
- loop-termination-proverSkill
- macro-expanderSkill
- memory-allocatorSkill
- message-passing-systemSkill
- mlir-dialect-designerSkill
- model-checkerSkill
- module-systemSkill
- monad-transformerSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 3 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 318
Start with simple types
- Distinctive: line 319
Use domain theory for recursion
- Distinctive: line 383
Not all fixed-points compute correctly:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Denotational Semantics Builder
Constructs denotational semantic models for programming languages.
When to Use
- Formal semantics definition
- Proving program properties
- Semantic equivalence
- Language design
What This Skill Does
- Defines domains - Semantic domains
- Maps syntax - ⟦e⟧ : Exp → D
- Compositional - Meaning from parts
- Handles recursion - Fixed-point semantics
Core Theory
Denotational Semantics:
⟦e⟧ ∈ D where D is semantic domain
⟦n⟧ = ⟦n⟧ℤ ∈ ℤ
⟦x⟧ = ρ(x) ∈ D
⟦λx.e⟧ = λd. ⟦e⟧(ρ[x↦d])
⟦e₁ e₂⟧ = ⟦e₁⟧(⟦e₂⟧)Implementation
from typing import Dict, Callable, Generic, TypeVar, Set
from dataclasses import dataclass
# Semantic domains
Domain = TypeVar('Domain')
Value = TypeVar('Value')
# Basic domains
class Int:
"""Integers"""
def __init__(self, n: int):
self.n = n
class Bool:
"""Booleans"""
def __init__(self, b: bool):
self.b = b
# Function domain
class Fun(Generic[Domain, Value]):
"""Function domain D → E"""
def __init__(self, f: Callable[[Domain], Value]):
self.f = f
def apply(self, x: Domain) -> Value:
return self.f(x)
# Product domain
class Prod(Generic[Domain, Value]):
"""Product domain D × E"""
def __init__(self, first: Domain, second: Value):
self.first = first
self.second = second
# Environment
class Env(Dict[str, Value]):
"""Runtime environment"""
pass
# Denotational semantics
class DenotationalSemantics:
"""Denotational semantics for simple language"""
def __init__(self):
self.functions = {}
def sem_int(self, n: int) -> Int:
"""⟦n⟧ = n"""
return Int(n)
def sem_bool(self, b: bool) -> Bool:
"""⟦b⟧ = b"""
return Bool(b)
def sem_var(self, x: str, env: Env) -> Value:
"""⟦x⟧ = ρ(x)"""
return env[x]
def sem_lambda(self, x: str, body: 'Expr', env: Env) -> Value:
"""⟦λx.e⟧ = λd. ⟦e⟧(ρ[x↦d])"""
def semantics(d: Value) -> Value:
new_env = Env(env)
new_env[x] = d
return self.sem(body, new_env)
return Fun(semantics)
def sem_app(self, e1: 'Expr', e2: 'Expr', env: Env) -> Value:
"""⟦e₁ e₂⟧ = ⟦e₁⟧(⟦e₂⟧)"""
v1 = self.sem(e1, env)
v2 = self.sem(e2, env)
return v1.apply(v2)
def sem_if(self, cond: 'Expr', then: 'Expr', else_: 'Expr', env: Env) -> Value:
"""⟦if e then e₁ else e₂⟧"""
v = self.sem(cond, env)
if v.b:
return self.sem(then, env)
else:
return self.sem(else_, env)
def sem(self, expr: 'Expr', env: Env) -> Value:
"""Main semantics function"""
match expr:
case Int(n):
return self.sem_int(n)
case Bool(b):
return self.sem_bool(b)
case Var(x):
return self.sem_var(x, env)
case Lambda(x, body):
return self.sem_lambda(x, body, env)
case App(e1, e2):
return self.sem_app(e1, e2, env)
case If(cond, then, else_):
return self.sem_if(cond, then, else_, env)Fixed-Point Semantics
class RecursiveSemantics:
"""Semantics with recursion via fixed points"""
def __init__(self):
self.functions = {}
def fix(self, F: Callable[['Value'], 'Value']) -> 'Value':
"""Fixed-point computation (Kleene iteration)"""
# Start with bottom and iterate
x = None
while True:
fx = F(x)
if fx == x:
return x
x = fx
def sem_letrec(self, x: str, e1: 'Expr', e2: 'Expr', env: Env) -> Value:
"""⟦letrec x = e₁ in e₂⟧"""
# Create recursive environment
def F(f):
new_env = Env(env)
new_env[x] = f
return self.sem(e2, new_env)
# Compute fixed point
# This gives meaning to recursive definitions
return self.fix(F)
def sem_while(self, cond: 'Expr', body: 'Expr', env: Env) -> Value:
"""⟦while e do c⟧"""
while True:
v = self.sem(cond, env)
if not v.b:
return Bool(True)
self.sem(body, env)Domain Theory
class Domain:
"""Complete partial order"""
def __init__(self):
self.elements = set()
self.partial_order = {}
def lub(self, chain: Set['Value']) -> 'Value':
"""Least upper bound of chain"""
# In complete partial order: lub of chain exists
pass
def bot(self) -> 'Value':
"""Bottom element (⊥)"""
pass
def le(self, x: 'Value', y: 'Value') -> bool:
"""Partial order (⊑)"""
pass
# Lifted domains
class Lifted(Generic[Domain]):
"""Domain with bottom"""
def __init__(self, d: Domain, bottom: Value):
self.domain = d
self.bottom = bottom
# Strict functions
class StrictFun(Domain):
"""Strict function (⊥ → ⊥ = ⊥)"""
def __init__(self, dom: Domain, cod: Domain):
self.domain = dom
self.codomain = cod
def apply(self, x: Value) -> Value:
if x == self.domain.bottom:
return self.codomain.bottom
# Apply function
passEquivalence Proof
class SemanticEquivalence:
"""Prove semantic equivalence"""
def prove_eq(self, e1: 'Expr', e2: 'Expr') -> bool:
"""Prove ⟦e₁⟧ = ⟦e₂⟧"""
# Compute denotations
d1 = self.sem(e1, {})
d2 = self.sem(e2, {})
return d1 == d2
def prove_extensional(self, e1: 'Expr', e2: 'Expr') -> bool:
"""
Extensional equality:
∀ρ. ⟦e₁⟧ρ = ⟦e₂⟧ρ
"""
# Test various environments
test_envs = self.generate_test_envs()
for env in test_envs:
d1 = self.sem(e1, env)
d2 = self.sem(e2, env)
if d1 != d2:
return False
return TrueDenotational vs Operational
Operational: How program executes (steps)
⟦e⟧ → v (one step at a time)
Denotational: What program means (mathematical)
⟦e⟧ ∈ D (direct mapping)
Relationship:
Operational → Denotational (adequacy)
Denotational → Operational (full abstraction)Key Concepts
| Concept | Description |
| Semantic domain | Mathematical structure |
| Compositional | Meaning from parts |
| Fixed point | Recursion semantics |
| Adequacy | Operational ↔ Denotational |
| Full abstraction | Context equivalence |
Canonical References
| Reference | Why It Matters |
| Stoy, "Denotational Semantics: The Scott-Strachey Approach to Programming Language Theory" (1977) | Definitive textbook on denotational semantics |
| Winskel, "The Formal Semantics of Programming Languages" (1993) | Comprehensive treatment |
| Abramsky & Jung, "Domain Theory" (1994) | Mathematical foundations |
| Gordon, "The Denotational Description of Programming Languages: An Introduction" (1979) | Introductory textbook |
Tips
- Start with simple types
- Use domain theory for recursion
- Prove adequacy after
- Consider extensionality
Related Skills
operational-semantics-definer- Operational semanticshoare-logic-verifier- Axiomatic semanticslambda-calculus-interpreter- Lambda calculus
Research Tools & Artifacts
Domain theory and denotational semantics tools:
| Resource | What to Learn |
| Stoy's "Denotational Semantics" | The foundational text |
| Winskel's "Formal Semantics" | Domain theory for programmers |
| Gunter, "Semantics of Programming Languages: Structures and Techniques" (1992) | Comprehensive coverage with domain theory |
| MLton | Whole-program compiler with semantic analysis |
Proof Assistant Formalizations
- Coq stdlib - Category theory, domain theory
- Iris - Higher-order separation logic
- Cartesian Closed Categories - Category theory for programming
Research Frontiers
1. Game Semantics
- Approach: Programs as strategies in games
- Advantage: Captures sequential behavior precisely
- Papers: "Full Abstraction for PCF" (Abramsky, Jagadeesan, Malacaria 2000; Hyland, Ong 2000)
- Application: Full abstraction for PCF, verification
2. Relational Semantics
- Approach: Relations between programs
- Advantage: Proves relational properties
- Papers: "Simple Relational Correctness Proofs for Static Analyses and Program Transformations" (Benton, 2004)
- Application: Program equivalence, compiler correctness
3. Metric Semantics
- Approach: Programs as points in metric spaces
- Advantage: Quantitative reasoning
- Papers: "Metric Semantics" (de Bakker, America)
- Application: Probabilistic programs, bisimulation
4. Step-Indexed Semantics
- Approach: Stratified semantic definitions
- Advantage: Handles recursion and step counting
- Papers: "An Indexed Model of Recursive Types" (Appel & McAllester, 2001)
- Application: Foundational proof-carrying code, separation logic
Implementation Pitfalls
| Pitfall | Real Consequence | Solution |
| Missing bottom element | Non-termination not represented | Add ⊥ to all domains |
| Non-continuous functions | Fixed-point may not exist | Ensure monotonicity |
| Wrong domain lift | Strictness issues | Use strict function space |
| Inadequate adequacy | Semantics doesn't match behavior | Prove adequacy theorem |
The "Fixed-Point Needs Continuity" Problem
Not all fixed-points compute correctly:
# WRONG: Non-monotonic function
def F(f):
if f(0) > 0: return lambda x. 0
else: return lambda x. 1
# RIGHT: Monotonic function (for denotational)
# f is monotonic: if a ⊑ b then F(a) ⊑ F(b)
# Then Kleene fixed-point convergesThe "Adequacy Gap"
Operational and denotational semantics must match:
Denotational: ⟦e⟧ = ⊥ (doesn't terminate)
Operational: e →* ⊥ (diverges)
Adequacy: If ⟦e⟧ = v then e →* v
If ⟦e⟧ = ⊥ then e diverges (or gets stuck)Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

