Skip to main content
⚡ Calmops

Formal Semantics

Introduction

Formal semantics studies how to assign meaning to formal languages. It answers questions like:

  • What does a program mean?
  • What does a formula mean?
  • How do we define the meaning of language constructs?
  • How do we verify that two programs are equivalent?

Formal semantics is essential for:

  • Programming language design
  • Compiler construction
  • Program verification
  • Formal specification
  • Artificial intelligence

In this article, we’ll explore the major approaches to formal semantics.

Semantics Approaches

Three Main Approaches

Denotational Semantics:

Maps programs to mathematical objects (denotations)
Focuses on what programs compute

Operational Semantics:

Defines how programs execute step-by-step
Focuses on how programs compute

Axiomatic Semantics:

Specifies properties of programs using logical assertions
Focuses on what we can prove about programs

Denotational Semantics

Definition

Denotational semantics assigns mathematical meaning to language constructs.

Formal Definition:

⟦·⟧: Language → Mathematical Objects
⟦program⟧ = mathematical object representing program's meaning

Examples

Arithmetic Expressions:

⟦5⟧ = 5
⟦x + 3⟧ = λσ. σ(x) + 3  (function of state)
⟦2 * 3⟧ = 6

Boolean Expressions:

⟦true⟧ = true
⟦x > 5⟧ = λσ. σ(x) > 5  (function of state)
⟦P ∧ Q⟧ = λσ. ⟦P⟧(σ) ∧ ⟦Q⟧(σ)

Statements:

⟦skip⟧ = λσ. σ  (identity function)
⟦x := 5⟧ = λσ. σ[x ↦ 5]  (update state)
⟦S₁; S₂⟧ = λσ. ⟦S₂⟧(⟦S₁⟧(σ))  (composition)

Advantages

Mathematical Rigor:

Precise mathematical definitions
Enables formal proofs

Compositionality:

Meaning of whole = function of meanings of parts
Enables modular reasoning

Abstraction:

Ignores implementation details
Focuses on essential behavior

Disadvantages

Complexity:

Can be difficult to understand
Requires mathematical sophistication

Abstraction:

May hide important details
Difficult to reason about efficiency

Operational Semantics

Definition

Operational semantics defines how programs execute by specifying state transitions.

Formal Definition:

⟨program, state⟩ → ⟨program', state'⟩
Describes one step of execution

Small-Step Semantics

Small-step semantics defines individual computation steps.

Example: Arithmetic:

⟨2 + 3, σ⟩ → ⟨5, σ⟩
⟨x + 3, σ⟩ → ⟨σ(x) + 3, σ⟩
⟨(2 + 3) * 4, σ⟩ → ⟨5 * 4, σ⟩ → ⟨20, σ⟩

Example: Statements:

⟨x := 5; y := x + 1, σ⟩ → ⟨y := x + 1, σ[x ↦ 5]⟩
⟨y := x + 1, σ[x ↦ 5]⟩ → ⟨skip, σ[x ↦ 5, y ↦ 6]⟩

Big-Step Semantics

Big-step semantics defines complete evaluation.

Notation:

⟨program, state⟩ ⇓ ⟨result, state'⟩
Program evaluates to result in new state

Example:

⟨2 + 3, σ⟩ ⇓ ⟨5, σ⟩
⟨x := 5; y := x + 1, σ⟩ ⇓ ⟨skip, σ[x ↦ 5, y ↦ 6]⟩

Advantages

Intuitive:

Easy to understand
Matches how we think about execution

Concrete:

Specifies actual behavior
Useful for implementation

Debuggable:

Can trace execution steps
Useful for understanding programs

Disadvantages

Complexity:

Many rules needed for complete language
Difficult to reason about

Implementation-Dependent:

May depend on execution order
Difficult to abstract

Axiomatic Semantics

Definition

Axiomatic semantics specifies program properties using logical assertions.

Hoare Triple:

{P} S {Q}
P: precondition (what must be true before)
S: statement
Q: postcondition (what must be true after)

Examples

Assignment:

{x = 5} x := x + 1 {x = 6}
Before: x is 5
After: x is 6

Sequence:

{P} S₁ {R}
{R} S₂ {Q}
─────────────
{P} S₁; S₂ {Q}

Conditional:

{P ∧ B} S₁ {Q}
{P ∧ ¬B} S₂ {Q}
──────────────────────
{P} if B then S₁ else S₂ {Q}

Loop:

{I} S {I}
──────────────────
{I} while B do S {I ∧ ¬B}
I: loop invariant (true before, during, after loop)

Advantages

Verification:

Can prove program correctness
Enables formal verification

Abstraction:

Focuses on properties
Ignores implementation details

Modularity:

Can reason about parts independently
Enables compositional reasoning

Disadvantages

Difficulty:

Requires mathematical skill
Difficult to find invariants

Incompleteness:

Cannot prove all true properties
Some properties are unprovable

Semantic Equivalence

Definition

Two programs are semantically equivalent if they have the same meaning.

Formal Definition:

P₁ ≡ P₂ iff ⟦P₁⟧ = ⟦P₂⟧
(same denotation)

Examples

Arithmetic:

2 + 3 ≡ 5
x + 0 ≡ x
x + y ≡ y + x

Programs:

x := 5; y := x + 1 ≡ x := 5; y := 6
while x > 0 do x := x - 1 ≡ (loop that decrements x to 0)

Verification

Denotational:

Show ⟦P₁⟧ = ⟦P₂⟧

Operational:

Show ⟨P₁, σ⟩ ⇓ ⟨r₁, σ'⟩ and ⟨P₂, σ⟩ ⇓ ⟨r₂, σ'⟩
with r₁ = r₂

Axiomatic:

Show {P} P₁ {Q} iff {P} P₂ {Q}

Glossary

  • Semantics: Study of meaning
  • Denotational semantics: Maps to mathematical objects
  • Operational semantics: Defines execution steps
  • Axiomatic semantics: Specifies properties
  • Denotation: Mathematical meaning
  • State: Values of variables
  • Transition: One step of execution
  • Hoare triple: Assertion about program
  • Precondition: Condition before execution
  • Postcondition: Condition after execution
  • Loop invariant: Property maintained by loop
  • Semantic equivalence: Programs have same meaning

Practice Problems

Problem 1: Denotational Semantics

Define ⟦x + y⟧ denotationally.

Solution:

⟦x + y⟧ = λσ. σ(x) + σ(y)
(function that takes state and returns sum of x and y values)

Problem 2: Operational Semantics

Give small-step semantics for x := 5; y := x + 1.

Solution:

⟨x := 5; y := x + 1, σ⟩ → ⟨y := x + 1, σ[x ↦ 5]⟩
⟨y := x + 1, σ[x ↦ 5]⟩ → ⟨y := 5 + 1, σ[x ↦ 5]⟩
⟨y := 5 + 1, σ[x ↦ 5]⟩ → ⟨y := 6, σ[x ↦ 5]⟩
⟨y := 6, σ[x ↦ 5]⟩ → ⟨skip, σ[x ↦ 5, y ↦ 6]⟩

Problem 3: Axiomatic Semantics

Prove {x = 5} x := x + 1 {x = 6}.

Solution:

Precondition: x = 5
Assignment: x := x + 1
Postcondition: x = 6

By assignment rule:
{x + 1 = 6} x := x + 1 {x = 6}
Simplify: {x = 5} x := x + 1 {x = 6}
Proven.

Problem 4: Semantic Equivalence

Are x := 5; y := 10 and y := 10; x := 5 equivalent?

Solution:

Yes. Both statements set x to 5 and y to 10.
Final state is the same regardless of order.
⟦x := 5; y := 10⟧ = ⟦y := 10; x := 5⟧

Online Platforms

Interactive Tools

  • “Semantics with Applications” by Winskel - Comprehensive coverage
  • “Formal Semantics of Programming Languages” by Gunter - Advanced treatment
  • “Programming Language Pragmatics” by Scott - Practical approach
  • “Types and Programming Languages” by Pierce - Modern approach
  • “The Formal Semantics of Programming Languages” by Winskel & Nielsen - Classic text

Academic Journals

Software Tools

Conclusion

Formal semantics provides rigorous meaning to languages:

  • Denotational: Mathematical objects represent meaning
  • Operational: Execution steps define behavior
  • Axiomatic: Logical assertions specify properties
  • Equivalence: Programs with same meaning
  • Verification: Proving program correctness

Understanding formal semantics is essential for programming language design, compiler construction, and program verification.

In the next article, we’ll explore Boolean Algebra, which provides the foundation for logic circuits and digital design.


Next Article: Boolean Algebra: Operations and Laws

Previous Article: Completeness and Soundness

Comments