Revenue Reports

Company performance analysis from multiple financial documents. The system grows from a minimal base as evidence is ingested, with quote verification catching fabricated claims, taint propagation marking downstream derivations, and manual override correcting specific facts.

Files

"""
Demo: Revenue Reports

Scenario: Company performance analysis from multiple financial documents.
The system grows from a minimal base as evidence is ingested, with quote
verification catching fabricated claims, taint propagation marking
downstream derivations, and manual override correcting specific facts.
"""

import json
import logging
import os
import sys

from parseltongue.core import Symbol, System, load_source


def _print_list(items):
    for item in items:
        if isinstance(item, dict):
            origin = item.get("origin", "")
            tag = str(origin) if hasattr(origin, "is_grounded") else f"[origin: {origin}]"
            print(f"  {item['name']} = {item['value']} {tag}")
        else:
            print(f"  {item}")


def main():
    plog = logging.getLogger("parseltongue")
    plog.setLevel(logging.WARNING)
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(logging.Formatter("  [%(levelname)s] %(message)s"))
    plog.addHandler(handler)

    s = System(overridable=True)
    print("=" * 60)
    print("Parseltongue DSL — Self-Extending Formal System")
    print("=" * 60)

    # ----------------------------------------------------------
    # Phase 0: Load source documents
    # ----------------------------------------------------------
    print("\n--- Phase 0: Load source documents ---")
    doc_dir = os.path.join(os.path.dirname(__file__), "resources")
    s.load_document("Q3 Report", os.path.join(doc_dir, "q3_report.txt"))
    s.load_document("FY2024 Targets Memo", os.path.join(doc_dir, "targets_memo.txt"))
    s.load_document("Bonus Policy Doc", os.path.join(doc_dir, "bonus_policy.txt"))
    print(f"  Loaded {len(s.documents)} source documents")
    for name in s.documents:
        print(f"    - {name}")

    # ----------------------------------------------------------
    # Phase 1: Base system — just arithmetic, logic, comparison
    # ----------------------------------------------------------
    print("\n--- Phase 1: Base system ---")
    print(f"Starting with: {s}")
    print(f"  (+ 2 3) = {s.evaluate([Symbol('+'), 2, 3])}")
    print(f"  (> 15 10) = {s.evaluate([Symbol('>'), 15, 10])}")

    # ----------------------------------------------------------
    # Phase 2: Ingest Q3 Report with quote-verified evidence
    # ----------------------------------------------------------
    print("\n--- Phase 2: Ingest Q3 Report (with quote verification) ---")

    load_source(
        s,
        """
        (fact revenue-q3 15.0
          :evidence (evidence "Q3 Report"
            :quotes ("Q3 revenue was $15M")
            :explanation "Dollar revenue figure from Q3 report"))

        (fact revenue-q3-growth 15
          :evidence (evidence "Q3 Report"
            :quotes ("up 15% year-over-year")
            :explanation "YoY growth percentage"))
    """,
    )

    print(f"  System now: {s}")
    _print_list(s.list_facts())

    # ----------------------------------------------------------
    # Phase 3: Ingest Targets Memo with evidence
    # ----------------------------------------------------------
    print("\n--- Phase 3: Ingest Targets Memo (with quote verification) ---")

    load_source(
        s,
        """
        (fact growth-target 10
          :evidence (evidence "FY2024 Targets Memo"
            :quotes ("Revenue growth target for FY2024: 10%")
            :explanation "The board-set target percentage"))

        (defterm beat-target
            (> revenue-q3-growth growth-target)
            :evidence (evidence "FY2024 Targets Memo"
              :quotes ("Exceeding the growth target is defined as achieving year-over-year revenue growth above the stated target percentage")
              :explanation "Definition of what it means to beat the target"))
    """,
    )

    print(f"  System now: {s}")

    # ----------------------------------------------------------
    # Phase 4: LLM-guided derivation (grounded sources)
    # ----------------------------------------------------------
    print("\n--- Phase 4: Derivation from verified sources ---")

    load_source(
        s,
        """
        (derive target-exceeded
            (> revenue-q3-growth growth-target)
            :using (revenue-q3-growth growth-target))
    """,
    )

    result = s.evaluate(s.terms["beat-target"].definition)
    print(f"  beat-target evaluates to: {result}")
    _print_list(s.list_axioms())

    # ----------------------------------------------------------
    # Phase 5: Provenance trace with verification details
    # ----------------------------------------------------------
    print("\n--- Phase 5: Provenance trace ---")
    prov = s.provenance("target-exceeded")
    print(json.dumps(prov, indent=2))

    # ----------------------------------------------------------
    # Phase 6: Fabricated quote — flagged, not rejected
    # ----------------------------------------------------------
    print("\n--- Phase 6: Fabricated quote detection ---")

    load_source(
        s,
        """
        (fact fake-metric 999
          :evidence (evidence "Q3 Report"
            :quotes ("Q3 revenue was $999M, a record-breaking quarter")
            :explanation "This quote does not exist in the document"))
    """,
    )

    print("  fake-metric accepted but flagged:")
    _print_list(s.list_facts())

    # ----------------------------------------------------------
    # Phase 7: Fabrication propagation through derivation
    # ----------------------------------------------------------
    print("\n--- Phase 7: Fabrication propagation ---")

    load_source(
        s,
        """
        (derive uses-fake
            (> fake-metric 0)
            :using (fake-metric))
    """,
    )

    print("  Derivation from unverified source:")
    _print_list(s.list_axioms())

    # ----------------------------------------------------------
    # Phase 8: Manual override
    # ----------------------------------------------------------
    print("\n--- Phase 8: Manual override ---")
    print("  Before override:")
    _print_list(s.list_facts())

    s.verify_manual("fake-metric")

    print("  After override:")
    _print_list(s.list_facts())

    # ----------------------------------------------------------
    # Phase 9: Cross-document inference with verified evidence
    # ----------------------------------------------------------
    print("\n--- Phase 9: Cross-document inference ---")

    load_source(
        s,
        """
        (fact base-salary 150000
          :evidence (evidence "Bonus Policy Doc"
            :quotes ("Base salary for eligible employees is $150,000")
            :explanation "Base salary from HR policy"))

        (fact bonus-rate 0.20
          :evidence (evidence "Bonus Policy Doc"
            :quotes ("Bonus is 20% of base salary if growth target is exceeded")
            :explanation "Bonus rate from policy"))

        (defterm bonus-amount
            (if (> revenue-q3-growth growth-target)
                (* base-salary bonus-rate)
                0)
            :evidence (evidence "Bonus Policy Doc"
              :quotes ("Bonus is 20% of base salary if growth target is exceeded"
                       "Eligibility requires that the quarterly revenue growth exceeds the stated annual growth target")
              :explanation "Bonus calculation formula and eligibility criteria"))
    """,
    )

    amount = s.evaluate(s.terms["bonus-amount"].definition)
    print(f"  Bonus amount: ${amount:,.0f}")

    load_source(
        s,
        """
        (derive bonus-confirmed
            (> (* base-salary bonus-rate) 0)
            :using (base-salary bonus-rate))
    """,
    )

    print("\n  Full provenance of bonus:")
    print(json.dumps(s.provenance("bonus-confirmed"), indent=2))

    # ----------------------------------------------------------
    # Phase 10: Diff — cross-source consistency check
    # ----------------------------------------------------------
    print("\n--- Phase 10: Diff — cross-source consistency check ---")

    # Add absolute revenue figures so we can compute growth independently
    load_source(
        s,
        """
        (fact revenue-q3-abs 230
          :origin "Q3 Report, revenue table")

        (fact revenue-q2 210
          :origin "Q2 Report, revenue table")

        ;; Compute growth from absolute figures
        (defterm revenue-q3-growth-computed
            (* (/ (- revenue-q3-abs revenue-q2) revenue-q2) 100)
            :origin "Derived from Q2/Q3 absolute revenue")
    """,
    )

    computed = s.evaluate(s.terms["revenue-q3-growth-computed"].definition)
    print("  Reported growth: 15%")
    print(f"  Computed growth: {computed:.2f}%")

    # Now diff: what changes if we use the computed value instead?
    load_source(
        s,
        """
        (diff growth-check
            :replace revenue-q3-growth
            :with revenue-q3-growth-computed)
    """,
    )

    print("\n  Diff result:")
    print(f"  {s.eval_diff('growth-check')}")

    # ----------------------------------------------------------
    # Phase 11: System consistency report
    # ----------------------------------------------------------
    print("\n--- Phase 11: System consistency report ---")
    report = s.consistency()
    print("\n  Full report:")
    print(f"  {report}")

    # ----------------------------------------------------------
    # Phase 12: Fix consistency issues
    # ----------------------------------------------------------
    print("\n--- Phase 12: Resolve consistency issues ---")

    # Fix 1: Verify base-salary evidence (quote failed due to line-break formatting)
    print("\n  Fix 1: Verify base-salary (formatting edge case)")
    s.verify_manual("base-salary")

    # Fix 2: Rederive tainted axioms now that sources are grounded
    print("\n  Fix 2: Rederive tainted axioms")
    s.rederive("bonus-confirmed")
    s.rederive("uses-fake")

    # Fix 3: Manually verify plain-origin items
    print("\n  Fix 3: Verify plain-origin items")
    s.verify_manual("revenue-q3-abs")
    s.verify_manual("revenue-q2")
    s.verify_manual("revenue-q3-growth-computed")

    # Fix 4: Correct revenue-q3-abs — if Q2=210 and growth=15%, Q3=241.5
    # overridable=True: auto-overwrites and recomputes dependent diffs
    print("\n  Fix 4: Correct revenue-q3-abs (auto-recomputes diffs)")
    s.set_fact("revenue-q3-abs", 241.5, "Corrected: 210 * 1.15 = 241.5 to match reported 15% growth")
    s.verify_manual("revenue-q3-abs")

    # Check consistency again
    print("\n  Consistency after fixes:")
    report = s.consistency()
    print("\n  Full report:")
    print(f"  {report}")

    # ----------------------------------------------------------
    # Summary
    # ----------------------------------------------------------
    print("\n" + "=" * 60)
    print(f"Final system: {s}")
    print("\nAll axioms:")
    _print_list(s.list_axioms())
    print("\nAll terms:")
    _print_list(s.list_terms())
    print("\nAll facts:")
    _print_list(s.list_facts())


if __name__ == "__main__":
    main()
Bonus Policy Document

Section 1: Eligibility and Calculation

Bonus is 20% of base salary if growth target is exceeded. Base salary
for eligible employees is $150,000. Eligibility requires that the
quarterly revenue growth exceeds the stated annual growth target.

Bonuses are calculated at the end of each fiscal quarter and paid
within 30 days of quarter close. Pro-rated bonuses apply for employees
who joined mid-quarter.

Section 2: Accelerated Tier

Employees in divisions that exceed the growth target by more than 5
percentage points qualify for the accelerated bonus tier, which pays
30% of base salary instead of the standard 20%.

Section 3: Approval Process

All bonus payments require sign-off from the division VP and the
CFO. Disputed calculations should be escalated to HR within 15
business days of the bonus notification.
Q3 FY2024 Quarterly Report

Section 1: Revenue Performance

Q3 revenue was $15M, up 15% year-over-year. This represents the strongest
quarter in the company's history. Operating margins improved by 3 percentage
points compared to Q2, driven by cost optimization initiatives.

The revenue growth was primarily driven by expansion in the enterprise
segment, which saw a 22% increase in contract value. Customer retention
rate remained above 95% for the sixth consecutive quarter.

Section 2: Operational Highlights

Headcount grew to 450 employees, a net addition of 35 during the quarter.
Engineering velocity improved with a 20% reduction in average cycle time.
Three major product releases were shipped on schedule.

Section 3: Outlook

Management expects continued momentum into Q4, with preliminary indicators
suggesting revenue growth will remain in the double-digit range. Investment
in R&D will increase by 10% to support the product roadmap for FY2025.
FY2024 Targets Memo

Section 1: Overview

This memo establishes the key performance targets for FY2024 as approved
by the board of directors on January 15, 2024.

Section 2: Growth Objectives

2.1 Revenue Targets

Revenue growth target for FY2024: 10%. This target was set based on
market conditions and competitive analysis. The target reflects a
balanced approach between aggressive growth and sustainable operations.

2.2 Success Criteria

Exceeding the growth target is defined as achieving year-over-year
revenue growth above the stated target percentage. Divisions that
exceed the target by more than 5 percentage points will qualify for
the accelerated bonus tier.

Section 3: Efficiency Targets

Operating margin target: 18%. Customer acquisition cost should not
exceed $5,000 per enterprise customer. Employee productivity measured
as revenue per employee should increase by at least 8%.

Output

Click "Run in browser" to execute this demo with Pyodide.