let rec dist x = simplify_dist (
  match x with
  | Var v -> [(x, 1.)]
  | Lam (a, b) ->  (* ??? not sure if this is needed *)
      map (fun (b1,p) -> (Lam (a, b1)), p) (dist b)
  | App (a, b) -> (dist_apply a b)
  | Flip (p, a, b) ->
      (* FIXME: should check for p = 0 or 1 *)
      append (weight_dist p (dist a)) (weight_dist (1. -. p) (dist b))
  | Const _ -> [(x, 1.)]
  | Case _ -> [(x, 1.)])

(** Computes the distribution of a function application. *)

and dist_apply a b =
  match a with
  | Lam (x, s) ->
      if contains_var x s
      then   (* use the variable *)
        let app (b, bProb) =
          weight_dist bProb (dist (subst x b s))
        in concat (map app (dist b))
      else   (* don't use the arg.; just return dist of body *)
        dist s
  | Case branches ->   (* this definitely uses its arg. *)
      let dist_branch (b, bProb) =
        match b with
        | Const n ->
            weight_dist bProb (dist (assoc n branches))
        | Var _ -> raise (Prob_error "case: got a var"(* shouldn't happen *)
        | _ -> raise (Prob_error "error in case"in
      concat (map dist_branch (dist b))
  | _ -> [(App (a, b), 1.)]