Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Getting Started with AI for VLSI Engineers5
  • Just Enough AI: Models and Context15
  • Prompting13
  • Trust and Verification14
    • Hallucination and Failure Modes
    • Verifying AI Output
      • The Verify-First Checklist
      • Differential Testing Against a Reference
      • Property-Based Checks
      • Review the Diff, Not Just the Result
      • When to Refuse to Trust
    • Evaluating AI Tools for Your Team
  • Using AI for Engineering Work17
  • Engineering Walkthroughs7
  • Practical Foundations for AI Workflows4
  • Engineering Data5
  • Retrieval-Augmented Generation6
  • Agents and Tool Use18
  • Agent Design8
  • MCP and Skills6
  • Multi-Agent Design6
  • Practical Capstone6
  • Tokens, Cost and Latency12
  • Agentic Workflows for Chip Teams18
  • Interview and Judgment10
  • AI Skills: Full Course Index
  • Working with AI Glossary
  • Working with AI Cheatsheet
Loading lesson

‹Verifying AI Output
  1. Topics
  2. AI Skills for VLSI Engineers
  3. Trust and Verification
  4. Verifying AI Output
  5. Property-Based Checks

Verification and Safe Use · Beginner to Intermediate

Property-Based Checks

Check invariants that hold for every input, without writing a full reference model.

On this page

    Properties instead of a reference

    A property is a statement that holds for every input, such as commutativity or a range bound. Checking properties needs no reference model, only the specification restated as rules.

    One property rarely suffices. Four or five independent properties over the full input space catch most single-mistake implementations.

    Property kind

    Meaning

    Adder example

    Symmetry

    Input order does not matter

    add(a, b) equals add(b, a).

    Identity

    A neutral input changes nothing

    add(a, 0) equals (a, carry 0).

    Wrap rule

    Overflow follows modular arithmetic

    Sum bits equal (a + b) mod 16.

    Carry rule

    The carry flag matches the true sum

    Carry is 1 exactly when a + b >= 16.

    Round-trip

    Inverse operations cancel

    Decoding an encoded value returns the input.

    A runnable property check

    The program below uses a fake scripted function in place of a model. It checks 4 properties over all 256 operand pairs, then confirms the carry property catches a planted variant with its carry output stuck at 0.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    def gen_add4(a, b):
        # FAKE stand-in for an assistant-generated 4-bit adder, written for this course
        s = a + b
        return (s % 16, 1 if s >= 16 else 0)
    
    def plant_add4(a, b):
        # FAKE faulty variant with carry output stuck at 0, written for this course
        return ((a + b) % 16, 0)
    
    good = 0
    for a in range(16):
        for b in range(16):
            s, c = gen_add4(a, b)
            if gen_add4(b, a) == (s, c):
                good += 1
            if gen_add4(a, 0) == (a, 0):
                good += 1
            if s == (a + b) % 16:
                good += 1
            if c == (1 if a + b >= 16 else 0):
                good += 1
    plant_bad = 0
    for a in range(16):
        for b in range(16):
            if plant_add4(a, b)[1] != (1 if a + b >= 16 else 0):
                plant_bad += 1
    if good == 1024 and plant_bad == 120:
        print("PASS: 256 pairs satisfy 4 properties in 1024 checks, planted variant misses 120 carry checks")
    else:
        print("FAIL: good=%d plant_bad=%d" % (good, plant_bad))
        raise SystemExit(1)

    What the counts mean

    256 pairs times 4 properties gives 1024 checks, and all 1024 hold. The planted variant misses exactly 120 carry checks: pairs with a + b >= 16 number 256 - 136 = 120, since sums 0 to 15 take 16 + 15 + ... + 1 = 136 pairs.

    The 120 is again the harness proof. A carry rule that never fires on a stuck-at-0 carry is dead code, not a check.

    Common mistakes

    Common pitfall

    A property copied from the generated code restates the bug instead of checking it. Write each property from the specification before reading the generated implementation.

    Interview

    Likely probes: when properties beat a reference, and what makes a property set strong.

    • Properties win when no trusted reference exists yet, which is the usual case for new logic.

    • Strength comes from independence: symmetry, identity, wrap, and carry each fail differently.

    • A planted-bug count per property shows which properties actually fire.

    Check yourself All 1024 checks pass. Does that prove the adder correct?

    No. It proves these 4 properties hold on these 256 pairs. A mistake outside all four properties still escapes.

    Check yourself In the count above, why do sums 0 to 15 take exactly 136 pairs?

    Pair (a, b) with sum s has s + 1 solutions while s <= 15. Summing 1 through 16 gives 16 x 17 / 2 = 136.

    Related topics

    • Differential testing against a reference

    • Review the diff, not just the result

    Previous

    41 / 173

    Next: Review the Diff, Not Just the Result

    Up next

    Up nextReview the Diff, Not Just the Result

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • The Verify-First Checklist
    • When to Refuse to Trust