"A venture capital fund investing $50 million in 25 startups at equal sizes requires at least one 50x return and two 10x returns to achieve a 3x gross multiple."
The math does not work: the scenario described in the claim returns only 2.8x, falling $10 million short of the 3x gross multiple it claims to achieve.
What Was Claimed?
The claim states that a VC fund with $50 million invested equally across 25 startups needs at least one company to return 50 times its investment and two more to return 10 times their investment in order to achieve a 3x gross return for the whole fund. This kind of rule of thumb is common in venture capital education — the idea being that a fund needs one spectacular winner plus a few solid ones to return well. The question is whether the specific numbers actually add up.
What Did We Find?
The arithmetic is straightforward. A $50 million fund split equally across 25 companies puts $2 million into each company.
Under the claimed scenario, the 50x winner returns 50 × $2M = $100 million. The two 10x companies each return $20 million, for a combined $40 million. Everyone else returns nothing. Total proceeds: $140 million.
A 3x gross multiple on a $50 million fund requires $150 million in total proceeds. The described portfolio produces only $140 million — a $10 million shortfall, or 0.2x below the claimed threshold.
Two independent methods confirmed this. The algebraic formula (1×50 + 2×10) × $2M gives $140M. Explicitly listing all 25 companies — one at $100M, two at $20M each, twenty-two at $0 — and summing them also gives $140M. Both methods agree exactly.
The counter-evidence checks made the picture even clearer. Not only does the described scenario fail to reach 3x, but 3x is achievable through many other routes that involve no 50x return at all: 15 companies each returning 5x yields $150 million (exactly 3x), and 5 companies each returning 15x does the same. The claim fails both as a sufficiency statement (the described scenario is not sufficient) and as a necessity statement (a 50x return is not necessary).
One adversarial check explored what happens if the fund has 20 companies instead of 25. With $2.5 million per company, the same 1×50x + 2×10x pattern returns $175 million — 3.5x gross. This highlights that the number of portfolio companies is the key variable: with 25 companies the per-company stake is too small to reach 3x with this particular return pattern.
What Should You Keep In Mind?
This proof addresses the arithmetic of the specific scenario as stated. It does not evaluate whether a 50x return is desirable, likely, or important to a fund's strategy — only whether the described combination of returns is mathematically sufficient for 3x. Real fund math also involves fees, carry, recycling, and partial exits, none of which are captured here. The proof assumes a simplified model: equal allocation, binary outcomes (full multiple or zero), and gross returns only.
The claim may have originated from a slightly different fund structure — for example, a smaller number of companies or different allocation sizes — where the numbers do work out. The 3x threshold is also sensitive to portfolio size: the same return pattern works for funds with ≤23 equal-size investments.
How Was This Verified?
This is a pure mathematical proof with no external data sources — only arithmetic applied to the numbers stated in the claim. The proof script uses the proof-engine's compare() and explain_calc() functions from scripts/computations.py to perform and document each calculation, and includes a cross-check using an independent summation method. All steps are re-runnable.
Full details are available in the structured proof report, the full verification audit, and you can re-run the proof yourself.
What could challenge this verdict?
Check 1 — Can 3x be achieved without any 50x return?
Two alternative portfolios were computed: (a) 15 companies at 5x each, yielding 15 × 5 × $2M = $150M → 3.0x gross; (b) 5 companies at 15x each, yielding 5 × 15 × $2M = $150M → 3.0x gross. Both achieve the 3x threshold without any 50x return. The claim therefore also fails as a necessity condition — it is neither sufficient nor necessary.
Check 2 — What if the fund had 20 companies instead of 25?
With $50M / 20 companies = $2.5M each, the same 1×50x + 2×10x pattern returns (1×50 + 2×10) × $2.5M = $175M → 3.50x gross. This shows the number of portfolio companies is the critical variable: with 25 companies the per-company stake ($2M) is too small to reach 3x with this pattern. The pattern only clears 3x when the fund has ≤23 companies (per-company stake ≥ $2.143M).
Check 3 — Does the definition of "gross multiple" matter?
Both TVPI (total value to paid-in) and MOIC (multiple on invested capital) are computed identically at the fund level: total proceeds ÷ total invested capital. Both yield 2.8x for this scenario. No standard VC accounting convention changes the result.
None of the three checks found evidence that breaks or weakens the disproof.
Source: proof.py JSON summary (adversarial_checks)
detailed evidence
Evidence Summary
| ID | Fact | Verified |
|---|---|---|
| A1 | Per-company investment: $50M / 25 companies = $2M each | Computed: $2.0M per company |
| A2 | Total return under claimed scenario: (1×50 + 2×10) × $2M = $140M | Computed: $140.0M total return |
| A3 | Gross multiple achieved: $140M / $50M = 2.8x | Computed: 2.8000x (vs. claimed 3.0x) |
| A4 | Cross-check via direct portfolio sum: 1×$100M + 2×$20M + 22×$0M = $140M | Computed: $140.0M → 2.8000x (independently agrees) |
| A5 | Claim evaluation: gross_multiple == 3.0 | Computed: False (2.8x ≠ 3.0x) |
Source: proof.py JSON summary
Proof Logic
The fund invests $50M equally across 25 companies, placing $2.0M per company (A1).
Under the claimed scenario (1 company at 50x, 2 at 10x, 22 at 0x), the returns are: - 1 winner at 50x: 50 × $2M = $100M - 2 winners at 10x: 2 × 10 × $2M = $40M - 22 companies at 0x: $0M
Total return: $100M + $40M = $140M (A2).
Gross multiple: $140M / $50M = 2.8x (A3). The required gross multiple for a 3x return is $50M × 3 = $150M. The scenario falls $10M short of this target.
The cross-check (A4) independently confirms this by explicitly summing all 25 company returns (one at $100M, two at $20M each, twenty-two at $0M) and divides by $50M, also yielding 2.8000x. Both methods agree exactly.
The claim evaluation (A5) compares 2.8000 == 3.0, which is False. Verdict: DISPROVED.
Source: author analysis
Conclusion
Verdict: DISPROVED.
The claimed scenario (1×50x + 2×10x returns, others zero, on a $50M equal-size fund with 25 investments) yields a gross multiple of 2.8x, not 3x. The fund falls $10M short of the $150M required for 3x. This is a pure arithmetic result: 1×50 + 2×10 = 70 weighted units × $2M per unit = $140M < $150M.
Additionally, the claim fails as a necessity condition: multiple alternative portfolios achieve 3x without any 50x return.
This is a pure-math proof with no empirical citations. The verdict does not depend on any unverified sources.
audit trail
| Field | Value |
|---|---|
| Subject | A VC fund with $50M invested equally across 25 startups |
| Property | whether 1×50x + 2×10x returns (others=0) achieves a 3x gross multiple |
| Operator | == |
| Threshold | 3.0 |
| Proof direction | disprove |
| Operator note | Interpreted as a sufficiency claim: the stated returns (1 company at 50x, 2 at 10x, 22 at 0x) are sufficient to achieve a 3x gross multiple. Per-company investment: $50M/25 = $2M. Required return for 3x gross: $50M × 3 = $150M. Actual return under claimed scenario: (1×50 + 2×10)×$2M = $140M. $140M < $150M, so the claim is false. The claim also fails as a necessity claim: 3x is reachable without any 50x return. |
Source: proof.py JSON summary
Natural-language claim: A venture capital fund investing $50 million in 25 startups at equal sizes requires at least one 50x return and two 10x returns to achieve a 3x gross multiple.
Formal interpretation: The claim is read as a sufficiency claim — that 1 company returning 50x, 2 companies returning 10x, and the remaining 22 returning 0x is sufficient to achieve a 3x gross multiple on a $50M equal-allocation fund.
The operator is ==: the claimed scenario either yields 3.0x or it does not.
- Per-company investment: $50M / 25 = $2.0M
- Required total return for 3x gross: $50M × 3 = $150M
- Actual return under claimed scenario: (1×50 + 2×10) × $2M = $140M
- Since $140M < $150M, the claim is false.
The claim also fails as a necessity condition: 3x is reachable without any 50x return (see Counter-Evidence Search section).
Formalization scope: The natural-language claim uses "equal sizes," which the formal interpretation takes at face value as equal dollar allocations. The claim specifies exactly $50M across 25 companies — no ambiguity in the formalization. The formal interpretation is a faithful 1:1 mapping of the claim's arithmetic structure.
Source: proof.py JSON summary
============================================================
COMPUTATION
============================================================
A1: per-company investment ($M): fund_size_m / n_companies = 50.0 / 25 = 2.0000
-> $2.0M per company
Required total return for 3x gross ($M): fund_size_m * required_multiple = 50.0 * 3.0 = 150.0000
-> $150M needed
Return from 50x winner ($M): n_50x * multiple_50x * per_company_m = 1 * 50.0 * 2.0 = 100.0000
Return from 10x winners ($M): n_10x * multiple_10x * per_company_m = 2 * 10.0 * 2.0 = 40.0000
A2: total return under claimed scenario ($M): winner_50x_return_m + winner_10x_return_m = 100.0 + 40.0 = 140.0000
A3: gross multiple achieved: total_return_m / fund_size_m = 140.0 / 50.0 = 2.8000
Shortfall from 3x target ($M): required_return_m - total_return_m = 150.0 - 140.0 = 10.0000
-> The scenario falls $10M short of the $150M needed for 3x
============================================================
CROSS-CHECK
============================================================
Portfolio breakdown: 25 companies
Company 1 (50x): $100.0M
Companies 2-3 (10x each): $20.0M, $20.0M
Companies 4-25 (0x): $0.0M each
A4: Sum of all company returns = $140.0M
Cross-check gross multiple: $140.0M / $50M = 2.8000x
Cross-check: 2.8000x == 2.8000x [AGREE]
============================================================
VERDICT DETERMINATION
============================================================
A5: gross_multiple == 3.0: 2.8 == 3.0 = False
Verdict: DISPROVED
Gross multiple achieved: 2.8000x
Required (claimed): 3.0x
Shortfall: $10.0M (0.2000x)
Source: proof.py inline output (execution trace)
Check 1 — Can a 3x gross multiple be achieved without any 50x return?
- Question: Can a 3x gross multiple be achieved without any 50x return? If yes, the 'necessity' reading of the claim is also false.
- Verification performed: Computed two alternative portfolios: (a) 15 companies at 5x each: 15 × 5 × $2M = $150M → 3.0x gross. (b) 5 companies at 15x each: 5 × 15 × $2M = $150M → 3.0x gross. Both achieve exactly 3x without any 50x return.
- Finding: 3x gross is achievable without any 50x return. Example: 15 companies at 5.0x each yields 3.0x gross; 5 companies at 15.0x each yields 3.0x gross. The claim fails as a necessity condition as well as a sufficiency condition.
- Breaks proof: No
Check 2 — What if the fund has fewer companies?
- Question: What if the fund has fewer companies (e.g., 20 instead of 25), keeping the same 1×50x + 2×10x pattern? Does the gross multiple change?
- Verification performed: Computed: $50M / 20 companies = $2.5M each. Return: (1×50 + 2×10) × $2.5M = $175.0M. Gross multiple: $175.0M / $50M = 3.50x.
- Finding: With 20 equal-size investments, the same 1×50x + 2×10x pattern yields 3.50x gross — which exceeds 3x. This shows the number of companies matters critically: the minimum required per-company investment to reach 3x with 1×50x + 2×10x is $150M / 70 = $2.143M, which requires ≤23 companies in a $50M fund. The claim specifies 25 companies ($2M each), which is too many to hit 3x with this pattern.
- Breaks proof: No
Check 3 — Does the definition of "gross multiple" matter?
- Question: Does the claim hold if 'gross multiple' refers to a return ON INVESTED capital rather than total value returned (i.e., 2.8x TVPI vs. 3x MOIC interpretation)?
- Verification performed: Confirmed standard VC terminology: gross multiple = TVPI (total value to paid-in), which is total proceeds divided by total invested capital. MOIC (multiple on invested capital) is computed identically at the fund level. Both give 2.8x for this scenario.
- Finding: Both TVPI and MOIC yield 2.8x for this scenario. No alternative definition of 'gross multiple' changes the arithmetic. The claim is false under any standard VC accounting convention.
- Breaks proof: No
Source: proof.py JSON summary
| Rule | Status |
|---|---|
| Rule 1: Every empirical value parsed from quote text, not hand-typed | N/A — pure computation, no empirical facts |
| Rule 2: Every citation URL fetched and quote checked | N/A — pure computation, no empirical facts |
| Rule 3: System time used for date-dependent logic | PASS — date.today() anchors generated_at |
| Rule 4: Claim interpretation explicit with operator rationale | PASS — CLAIM_FORMAL with operator_note states exact interpretation and arithmetic |
| Rule 5: Adversarial checks searched for independent counter-evidence | PASS — 3 adversarial checks; alternative portfolios computed; terminology verified |
| Rule 6: Cross-checks used independently sourced inputs | N/A — pure computation, no empirical facts; cross-check uses independent algebraic method |
| Rule 7: Constants and formulas imported from computations.py, not hand-coded | PASS — compare() and explain_calc() from scripts.computations |
| validate_proof.py result | PASS — 14/14 checks passed, 0 issues, 0 warnings |
Source: author analysis
Cite this proof
Proof Engine. (2026). Claim Verification: “A venture capital fund investing $50 million in 25 startups at equal sizes requires at least one 50x return and two 10x returns to achieve a 3x gross multiple.” — Disproved. https://proofengine.info/proofs/a-venture-capital-fund-investing-50-million-in-25-startups-at-equal-sizes/
Proof Engine. "Claim Verification: “A venture capital fund investing $50 million in 25 startups at equal sizes requires at least one 50x return and two 10x returns to achieve a 3x gross multiple.” — Disproved." 2026. https://proofengine.info/proofs/a-venture-capital-fund-investing-50-million-in-25-startups-at-equal-sizes/.
@misc{proofengine_a_venture_capital_fund_investing_50_million_in_25_startups_at_equal_sizes,
title = {Claim Verification: “A venture capital fund investing $50 million in 25 startups at equal sizes requires at least one 50x return and two 10x returns to achieve a 3x gross multiple.” — Disproved},
author = {{Proof Engine}},
year = {2026},
url = {https://proofengine.info/proofs/a-venture-capital-fund-investing-50-million-in-25-startups-at-equal-sizes/},
note = {Verdict: DISPROVED. Generated by proof-engine v1.10.0},
}
TY - DATA TI - Claim Verification: “A venture capital fund investing $50 million in 25 startups at equal sizes requires at least one 50x return and two 10x returns to achieve a 3x gross multiple.” — Disproved AU - Proof Engine PY - 2026 UR - https://proofengine.info/proofs/a-venture-capital-fund-investing-50-million-in-25-startups-at-equal-sizes/ N1 - Verdict: DISPROVED. Generated by proof-engine v1.10.0 ER -
View proof source
This is the proof.py that produced the verdict above. Every fact traces to code below. (This proof has not yet been minted to Zenodo; the source here is the working copy from this repository.)
"""
Proof: A venture capital fund investing $50 million in 25 startups at equal sizes
requires at least one 50x return and two 10x returns to achieve a 3x gross multiple.
Generated: 2026-04-08
"""
import os
import sys
PROOF_ENGINE_ROOT = os.environ.get("PROOF_ENGINE_ROOT")
if not PROOF_ENGINE_ROOT:
_d = os.path.dirname(os.path.abspath(__file__))
while _d != os.path.dirname(_d):
if os.path.isdir(os.path.join(_d, "proof-engine", "skills", "proof-engine", "scripts")):
PROOF_ENGINE_ROOT = os.path.join(_d, "proof-engine", "skills", "proof-engine")
break
_d = os.path.dirname(_d)
if not PROOF_ENGINE_ROOT:
raise RuntimeError("PROOF_ENGINE_ROOT not set and skill dir not found via walk-up from proof.py")
sys.path.insert(0, PROOF_ENGINE_ROOT)
from datetime import date
from scripts.computations import compare, explain_calc, emit_proof_summary
# =============================================================================
# 1. CLAIM INTERPRETATION (Rule 4)
# =============================================================================
CLAIM_NATURAL = (
"A venture capital fund investing $50 million in 25 startups at equal sizes "
"requires at least one 50x return and two 10x returns to achieve a 3x gross multiple."
)
CLAIM_FORMAL = {
"subject": "A VC fund with $50M invested equally across 25 startups",
"property": "whether 1×50x + 2×10x returns (others=0) achieves a 3x gross multiple",
"operator": "==",
"operator_note": (
"Interpreted as a sufficiency claim: the stated returns (1 company at 50x, 2 at 10x, "
"22 at 0x) are sufficient to achieve a 3x gross multiple. "
"Per-company investment: $50M/25 = $2M. "
"Required return for 3x gross: $50M × 3 = $150M. "
"Actual return under claimed scenario: (1×50 + 2×10)×$2M = $140M. "
"$140M < $150M, so the claim is false. "
"The claim also fails as a necessity claim: 3x is reachable without any 50x return."
),
"threshold": 3.0,
"proof_direction": "disprove",
}
# =============================================================================
# 2. FACT REGISTRY — A-types only for pure math
# =============================================================================
FACT_REGISTRY = {
"A1": {
"label": "Per-company investment: $50M / 25 companies = $2M each",
"method": None,
"result": None,
},
"A2": {
"label": "Total return under claimed scenario: (1×50 + 2×10) × $2M = $140M",
"method": None,
"result": None,
},
"A3": {
"label": "Gross multiple achieved: $140M / $50M = 2.8x",
"method": None,
"result": None,
},
"A4": {
"label": "Cross-check via direct portfolio sum: 1×$100M + 2×$20M + 22×$0M = $140M",
"method": None,
"result": None,
},
"A5": {
"label": "Claim evaluation: gross_multiple == 3.0",
"method": None,
"result": None,
},
}
# =============================================================================
# 3. COMPUTATION — primary method (Rule 7)
# =============================================================================
print("=" * 60)
print("COMPUTATION")
print("=" * 60)
# Fund parameters
fund_size_m = 50.0 # $50M total fund
n_companies = 25 # equal-size investments
required_multiple = 3.0 # claimed gross multiple
# Per-company investment
per_company_m = explain_calc(
"fund_size_m / n_companies",
{"fund_size_m": fund_size_m, "n_companies": n_companies},
label="A1: per-company investment ($M)",
)
print(f" -> ${per_company_m:.1f}M per company")
# Required total return for 3x gross
required_return_m = explain_calc(
"fund_size_m * required_multiple",
{"fund_size_m": fund_size_m, "required_multiple": required_multiple},
label="Required total return for 3x gross ($M)",
)
print(f" -> ${required_return_m:.0f}M needed")
# Returns under the claimed scenario: 1 company at 50x, 2 at 10x, 22 at 0x
n_50x = 1
n_10x = 2
multiple_50x = 50.0
multiple_10x = 10.0
winner_50x_return_m = explain_calc(
"n_50x * multiple_50x * per_company_m",
{"n_50x": n_50x, "multiple_50x": multiple_50x, "per_company_m": per_company_m},
label="Return from 50x winner ($M)",
)
winner_10x_return_m = explain_calc(
"n_10x * multiple_10x * per_company_m",
{"n_10x": n_10x, "multiple_10x": multiple_10x, "per_company_m": per_company_m},
label="Return from 10x winners ($M)",
)
total_return_m = explain_calc(
"winner_50x_return_m + winner_10x_return_m",
{"winner_50x_return_m": winner_50x_return_m, "winner_10x_return_m": winner_10x_return_m},
label="A2: total return under claimed scenario ($M)",
)
# Gross multiple achieved
gross_multiple = explain_calc(
"total_return_m / fund_size_m",
{"total_return_m": total_return_m, "fund_size_m": fund_size_m},
label="A3: gross multiple achieved",
)
shortfall_m = explain_calc(
"required_return_m - total_return_m",
{"required_return_m": required_return_m, "total_return_m": total_return_m},
label="Shortfall from 3x target ($M)",
)
print(f" -> The scenario falls ${shortfall_m:.0f}M short of the $150M needed for 3x")
# =============================================================================
# 4. CROSS-CHECK — mathematically independent method (Rule 6)
# =============================================================================
print("\n" + "=" * 60)
print("CROSS-CHECK")
print("=" * 60)
# Independent method: list each company's return explicitly and sum
# Company 1: 50x on $2M = $100M
# Companies 2-3: 10x on $2M each = $20M each = $40M total
# Companies 4-25: 0x on $2M each = $0
company_returns = (
[n_50x * multiple_50x * per_company_m] # 1 company at 50x
+ [multiple_10x * per_company_m] * n_10x # 2 companies at 10x
+ [0.0] * (n_companies - n_50x - n_10x) # 22 companies at 0x
)
print(f" Portfolio breakdown: {len(company_returns)} companies")
print(f" Company 1 (50x): ${company_returns[0]:.1f}M")
print(f" Companies 2-3 (10x each): ${company_returns[1]:.1f}M, ${company_returns[2]:.1f}M")
print(f" Companies 4-25 (0x): $0.0M each")
crosscheck_total_m = sum(company_returns)
crosscheck_multiple = crosscheck_total_m / fund_size_m
print(f" A4: Sum of all company returns = ${crosscheck_total_m:.1f}M")
print(f" Cross-check gross multiple: ${crosscheck_total_m:.1f}M / ${fund_size_m:.0f}M = {crosscheck_multiple:.4f}x")
assert abs(gross_multiple - crosscheck_multiple) < 1e-9, (
f"Cross-check failed: primary={gross_multiple}, crosscheck={crosscheck_multiple}"
)
print(f" Cross-check: {gross_multiple:.4f}x == {crosscheck_multiple:.4f}x [AGREE]")
# =============================================================================
# 5. ADVERSARIAL CHECKS (Rule 5)
# =============================================================================
print("\n" + "=" * 60)
print("ADVERSARIAL CHECKS")
print("=" * 60)
# Alternative scenario 1: can 3x be achieved WITHOUT a 50x return?
# E.g., 15 companies at 5x each: 15 × 5 × $2M = $150M → 3x gross
alt1_n = 15
alt1_multiple = 5.0
alt1_return_m = alt1_n * alt1_multiple * per_company_m
alt1_gross = alt1_return_m / fund_size_m
print(f"\nAdversarial check 1: Can 3x be achieved without any 50x return?")
print(f" Alternative: {alt1_n} companies at {alt1_multiple}x each")
print(f" Return: {alt1_n} × {alt1_multiple} × ${per_company_m:.1f}M = ${alt1_return_m:.1f}M")
print(f" Gross multiple: ${alt1_return_m:.1f}M / ${fund_size_m:.0f}M = {alt1_gross:.2f}x")
# Alternative scenario 2: 5 companies at 15x each
alt2_n = 5
alt2_multiple = 15.0
alt2_return_m = alt2_n * alt2_multiple * per_company_m
alt2_gross = alt2_return_m / fund_size_m
print(f"\n Alternative: {alt2_n} companies at {alt2_multiple}x each")
print(f" Return: {alt2_n} × {alt2_multiple} × ${per_company_m:.1f}M = ${alt2_return_m:.1f}M")
print(f" Gross multiple: ${alt2_return_m:.1f}M / ${fund_size_m:.0f}M = {alt2_gross:.2f}x")
# Alternative scenario 3: what if the fund had 20 companies instead of 25?
alt3_fund = 50.0
alt3_n = 20
alt3_per_co = alt3_fund / alt3_n # $2.5M each
alt3_return = (1 * 50 + 2 * 10) * alt3_per_co # same pattern, larger checks
alt3_gross = alt3_return / alt3_fund
print(f"\nAdversarial check 2: What if 20 companies instead of 25 (same portfolio pattern)?")
print(f" Per-company: $50M / 20 = ${alt3_per_co:.1f}M")
print(f" Return: (1×50 + 2×10) × ${alt3_per_co:.1f}M = ${alt3_return:.1f}M")
print(f" Gross multiple: ${alt3_return:.1f}M / ${alt3_fund:.0f}M = {alt3_gross:.2f}x")
print(f" Still < 3.0x? {alt3_gross < 3.0}")
adversarial_checks = [
{
"question": (
"Can a 3x gross multiple be achieved without any 50x return? "
"If yes, the 'necessity' reading of the claim is also false."
),
"verification_performed": (
"Computed two alternative portfolios: "
"(a) 15 companies at 5x each: 15 × 5 × $2M = $150M → 3.0x gross. "
"(b) 5 companies at 15x each: 5 × 15 × $2M = $150M → 3.0x gross. "
"Both achieve exactly 3x without any 50x return."
),
"finding": (
f"3x gross is achievable without any 50x return. "
f"Example: {alt1_n} companies at {alt1_multiple}x each yields {alt1_gross:.1f}x gross; "
f"{alt2_n} companies at {alt2_multiple}x each yields {alt2_gross:.1f}x gross. "
"The claim fails as a necessity condition as well as a sufficiency condition."
),
"breaks_proof": False,
},
{
"question": (
"What if the fund has fewer companies (e.g., 20 instead of 25), "
"keeping the same 1×50x + 2×10x pattern? Does the gross multiple change?"
),
"verification_performed": (
f"Computed: $50M / 20 companies = $2.5M each. "
f"Return: (1×50 + 2×10) × $2.5M = ${alt3_return:.1f}M. "
f"Gross multiple: ${alt3_return:.1f}M / $50M = {alt3_gross:.2f}x."
),
"finding": (
f"With 20 equal-size investments, the same 1×50x + 2×10x pattern yields "
f"{alt3_gross:.2f}x gross — which exceeds 3x. "
"This shows the number of companies matters critically: "
"the minimum required per-company investment to reach 3x with 1×50x + 2×10x "
"is $150M / 70 = $2.143M, which requires ≤ 23 companies in a $50M fund. "
"The claim specifies 25 companies ($2M each), which is too many to hit 3x with this pattern."
),
"breaks_proof": False,
},
{
"question": (
"Does the claim hold if 'gross multiple' refers to a return ON INVESTED capital "
"rather than total value returned (i.e., 2.8x TVPI vs. 3x MOIC interpretation)?"
),
"verification_performed": (
"Confirmed standard VC terminology: gross multiple = TVPI (total value to paid-in), "
"which is total proceeds divided by total invested capital. "
"MOIC (multiple on invested capital) is computed identically at the fund level. "
"Both give 2.8x for this scenario."
),
"finding": (
"Both TVPI and MOIC yield 2.8x for this scenario. "
"No alternative definition of 'gross multiple' changes the arithmetic. "
"The claim is false under any standard VC accounting convention."
),
"breaks_proof": False,
},
]
for i, check in enumerate(adversarial_checks):
print(f"\nAdversarial check {i+1}: {check['question'][:80]}...")
print(f" Breaks proof: {check['breaks_proof']}")
# =============================================================================
# 6. VERDICT AND STRUCTURED OUTPUT
# =============================================================================
if __name__ == "__main__":
print("\n" + "=" * 60)
print("VERDICT DETERMINATION")
print("=" * 60)
# For disproof: claim holds only if gross_multiple == required_multiple (3.0x)
claim_holds = compare(
gross_multiple,
CLAIM_FORMAL["operator"],
CLAIM_FORMAL["threshold"],
label="A5: gross_multiple == 3.0",
)
any_breaks = any(ac.get("breaks_proof") for ac in adversarial_checks)
# Pure-math disproof: no citations, no unverified-citation variants
if any_breaks:
verdict = "UNDETERMINED"
else:
verdict = "PROVED" if claim_holds else "DISPROVED"
print(f"\nVerdict: {verdict}")
print(f" Gross multiple achieved: {gross_multiple:.4f}x")
print(f" Required (claimed): {CLAIM_FORMAL['threshold']}x")
print(f" Shortfall: ${shortfall_m:.1f}M ({required_multiple - gross_multiple:.4f}x)")
# Populate Type A method/result
FACT_REGISTRY["A1"]["method"] = "fund_size_m / n_companies"
FACT_REGISTRY["A1"]["result"] = f"${per_company_m:.1f}M"
FACT_REGISTRY["A2"]["method"] = "(n_50x × multiple_50x + n_10x × multiple_10x) × per_company_m"
FACT_REGISTRY["A2"]["result"] = f"${total_return_m:.1f}M"
FACT_REGISTRY["A3"]["method"] = "total_return_m / fund_size_m"
FACT_REGISTRY["A3"]["result"] = f"{gross_multiple:.4f}x"
FACT_REGISTRY["A4"]["method"] = "sum([50x×$2M, 10x×$2M, 10x×$2M, 0x×$2M × 22])"
FACT_REGISTRY["A4"]["result"] = f"${crosscheck_total_m:.1f}M → {crosscheck_multiple:.4f}x"
FACT_REGISTRY["A5"]["method"] = f"compare({gross_multiple:.4f}, '==', {CLAIM_FORMAL['threshold']})"
FACT_REGISTRY["A5"]["result"] = str(claim_holds)
summary = {
"fact_registry": {
fid: {k: v for k, v in info.items()}
for fid, info in FACT_REGISTRY.items()
},
"claim_formal": CLAIM_FORMAL,
"claim_natural": CLAIM_NATURAL,
"cross_checks": [
{
"description": (
"Independent computation: explicit per-company list sum "
"vs. algebraic formula"
),
"values_compared": [f"{gross_multiple:.4f}x", f"{crosscheck_multiple:.4f}x"],
"agreement": abs(gross_multiple - crosscheck_multiple) < 1e-9,
},
],
"adversarial_checks": adversarial_checks,
"verdict": verdict,
"key_results": {
"fund_size_m": fund_size_m,
"n_companies": n_companies,
"per_company_m": per_company_m,
"total_return_m": total_return_m,
"gross_multiple": round(gross_multiple, 4),
"required_multiple": required_multiple,
"shortfall_m": shortfall_m,
"threshold": CLAIM_FORMAL["threshold"],
"operator": CLAIM_FORMAL["operator"],
"claim_holds": claim_holds,
},
"generator": {
"name": "proof-engine",
"version": open(os.path.join(PROOF_ENGINE_ROOT, "VERSION")).read().strip(),
"repo": "https://github.com/yaniv-golan/proof-engine",
"generated_at": date.today().isoformat(),
},
}
emit_proof_summary(summary)
Re-execute this proof
The verdict above is cached from when this proof was minted. To re-run the exact
proof.py shown in "View proof source" and see the verdict recomputed live,
launch it in your browser — no install required.
Re-execute from GitHub commit 1ba3732 — same bytes shown above.
First run takes longer while Binder builds the container image; subsequent runs are cached.
machine-readable formats
Downloads & raw data
found this useful? ★ star on github