@@ -837,7 +837,10 @@ fn check_bet(bet: &BetExpr, env: &mut CheckEnv, span: Span) -> CompileResult<Typ
837837
838838 env. unify ( & t0, & t1, Some ( span) ) ?;
839839 env. unify ( & t0, & t2, Some ( span) ) ?;
840- Ok ( env. resolve ( & t0) )
840+ // A `bet` introduces probabilistic choice: it has type `Dist T`, not `T`.
841+ // (Matches the mechanised rule `tBet : … → HasType … (Ty.dist T)` in
842+ // proofs/BetLang.lean; eliminate with `sample : Dist 'a -> 'a`.)
843+ Ok ( Type :: Dist ( Box :: new ( env. resolve ( & t0) ) ) )
841844}
842845
843846/// Check a weighted bet: branches unify, weights must be numeric.
@@ -863,7 +866,8 @@ fn check_weighted_bet(
863866 for i in 1 ..branch_types. len ( ) {
864867 env. unify ( & branch_types[ 0 ] , & branch_types[ i] , Some ( span) ) ?;
865868 }
866- Ok ( env. resolve ( & branch_types[ 0 ] ) )
869+ // Weighted bet, like uniform bet, is a distribution: `Dist T`.
870+ Ok ( Type :: Dist ( Box :: new ( env. resolve ( & branch_types[ 0 ] ) ) ) )
867871}
868872
869873/// Check a conditional bet: condition is Bool/Ternary, all branches unify.
@@ -892,7 +896,9 @@ fn check_conditional_bet(
892896 env. unify ( & true_ty, & f0, Some ( span) ) ?;
893897 env. unify ( & true_ty, & f1, Some ( span) ) ?;
894898 env. unify ( & true_ty, & f2, Some ( span) ) ?;
895- Ok ( env. resolve ( & true_ty) )
899+ // Conditional bet also yields a distribution over `T`: point-mass on the
900+ // `if_true` value when the condition holds, else the ternary distribution.
901+ Ok ( Type :: Dist ( Box :: new ( env. resolve ( & true_ty) ) ) )
896902}
897903
898904// ============================================
@@ -1265,7 +1271,11 @@ mod tests {
12651271 ] ,
12661272 } ;
12671273 let result = check_expr ( & dummy ( Expr :: Bet ( bet) ) , & mut env) ;
1268- assert_eq ! ( result. expect( "TODO: handle error" ) , Type :: Int ) ;
1274+ // `bet` introduces probabilistic choice, so its type is `Dist Int`.
1275+ assert_eq ! (
1276+ result. expect( "TODO: handle error" ) ,
1277+ Type :: Dist ( Box :: new( Type :: Int ) )
1278+ ) ;
12691279 }
12701280
12711281 #[ test]
@@ -1699,9 +1709,11 @@ mod tests {
16991709 ) ;
17001710 }
17011711
1702- /// The core primitive bridges to Echo by composition at the type level:
1703- /// `echo(bet a b c) : Echo T`. (Runtime branch-tag retention — `bet_echo` —
1704- /// remains deferred; the *type* story needs no new primitive.)
1712+ /// The core primitive bridges to Echo by composition at the type level.
1713+ /// Since `bet a b c : Dist T`, the composite is `echo(bet a b c) : Echo (Dist T)`
1714+ /// — the retained-loss residue over the *distribution*. (Runtime branch-tag
1715+ /// retention — `bet_echo` — remains deferred; the *type* story needs no new
1716+ /// primitive.)
17051717 #[ test]
17061718 fn test_bet_echo_bridge_by_composition ( ) {
17071719 let mut env = CheckEnv :: new ( ) ;
@@ -1714,8 +1726,8 @@ mod tests {
17141726 } ;
17151727 let e = call ( "echo" , vec ! [ dummy( Expr :: Bet ( bet) ) ] ) ;
17161728 assert_eq ! (
1717- check_expr( & e, & mut env) . expect( "echo (bet 1 2 3) : Echo Int" ) ,
1718- Type :: Echo ( Box :: new( Type :: Int ) )
1729+ check_expr( & e, & mut env) . expect( "echo (bet 1 2 3) : Echo (Dist Int) " ) ,
1730+ Type :: Echo ( Box :: new( Type :: Dist ( Box :: new ( Type :: Int ) ) ) )
17191731 ) ;
17201732 }
17211733
0 commit comments