Skip to content

Case Study: Bitul Shishim

An exploration of the 60:1 nullification rules in halacha, demonstrating how Mistaber handles ratio-based calculations and policy variations.

Overview

Bitul (nullification) is a fundamental concept in Yoreh Deah: when a forbidden substance is mixed with a permitted substance, under certain conditions, the forbidden substance can be "nullified" and the entire mixture becomes permitted.

The primary threshold is shishim (sixty) - a 60:1 ratio of permitted to forbidden.

This case study explores: - The basic bitul shishim rules - Exceptions where bitul doesn't apply - Policy variations between authorities - How Mistaber encodes these complex rules

The Halachic Framework

Basic Rule: 60:1 Nullification

From Yoreh Deah 98:

If a forbidden substance falls into a permitted substance, and the permitted substance is sixty times greater than the forbidden, the forbidden is nullified.

Example: If 1 gram of non-kosher meat falls into 60+ grams of kosher food, and doesn't give noticeable taste, the mixture is permitted.

Exceptions to Bitul

Several categories of forbidden items are never nullified:

Exception Hebrew Reason
Davar Sheyesh Lo Matirin דבר שיש לו מתירין Will become permitted later
Beriah בריה A complete creature
Chatichah Ha'reuya L'hitchabed חתיכה הראויה להתכבד A piece fit to serve guests
Davar Shebeminyan דבר שבמנין Items sold by count
Min B'mino מין במינו Same species mixing

Core ASP Implementation

Basic Bitul Rules

From mistaber/dsl/builtins/bitul.lp:

% Standard bitul threshold
bitul_ratio(60).

% Check if issur is nullified in mixture
issur_batel(M) :-
    mixture(M),
    ratio(M, R),
    bitul_ratio(T),
    R >= T,
    not min_lo_batel(M).

% Min (same species) is not nullified
min_lo_batel(M) :-
    mixture(M),
    contains(M, F1),
    contains(M, F2),
    F1 != F2,
    same_species(F1, F2).

% Same species check
same_species(F1, F2) :-
    food_type(F1, Category),
    food_type(F2, Category),
    specific_category(Category).

specific_category(beheima).
specific_category(chaya).
specific_category(of).
specific_category(dag).

Davar Sheyesh Lo Matirin

% Something that will become permitted is not nullified
davar_sheyesh_lo_matirin(M) :-
    mixture(M),
    contains(M, F),
    will_become_permitted(F).

% Override bitul for davar sheyesh lo matirin
min_lo_batel(M) :-
    mixture(M),
    davar_sheyesh_lo_matirin(M).

Practical Scenario: Milk in Meat Soup

Let's model a common scenario: a small amount of milk accidentally falls into a meat soup.

Scenario Definition

from pathlib import Path
from mistaber.engine import HsrsEngine

engine = HsrsEngine(Path("mistaber/ontology"))

scenario = """
% Define the foods
food(meat_soup).
food(milk_drop).

food_type(meat_soup, beheima).  % Meat component
food_type(milk_drop, chalav).

% The mixture
mixture(contaminated_soup).
contains(contaminated_soup, meat_soup).
contains(contaminated_soup, milk_drop).

% Volumes (in arbitrary units)
volume(meat_soup, 1000).    % 1000 units of soup
volume(milk_drop, 10).      % 10 units of milk

% Calculate ratio
ratio(contaminated_soup, 100).  % 1000/10 = 100:1
"""

result = engine.analyze(scenario, world="mechaber")

# Check if bitul applies
if any("issur_batel(contaminated_soup)" in a for a in result["atoms"]):
    print("The milk is NULLIFIED (batel) - soup is permitted")
else:
    print("The milk is NOT nullified - soup is forbidden")

Expected Result

With a 100:1 ratio (greater than 60), and different species (beheima vs chalav), the milk should be nullified:

The milk is NULLIFIED (batel) - soup is permitted

Min B'Mino: Same Species Exception

When the forbidden item is the same species as the permitted item, stricter rules apply:

The Rule

Normally, same species (min b'mino) cannot be nullified because the forbidden item is indistinguishable from the permitted.

Exception: If the issur doesn't give a noticeable bad taste (noten taam lifgam), it may still be nullified.

ASP Encoding

% Same species mixing - stricter standard
min_b_mino(M) :-
    mixture(M),
    contains(M, F1),
    contains(M, F2),
    F1 != F2,
    same_species(F1, F2).

% Min b'mino requires higher ratio or is not batel
min_lo_batel(M) :-
    min_b_mino(M),
    not noten_taam_lifgam(M).

% If the taste is pgam (spoiled/bad), it can still be batel
issur_batel(M) :-
    min_b_mino(M),
    noten_taam_lifgam(M),
    ratio(M, R),
    bitul_ratio(T),
    R >= T.

Example: Two Types of Meat

scenario = """
% Kosher and non-kosher beef mixed
food(kosher_beef).
food(treif_beef).

food_type(kosher_beef, beheima).
food_type(treif_beef, beheima).  % Same type!

mixture(beef_mix).
contains(beef_mix, kosher_beef).
contains(beef_mix, treif_beef).

volume(kosher_beef, 600).
volume(treif_beef, 10).
ratio(beef_mix, 60).

% Both are beheima - same species
same_species(kosher_beef, treif_beef).
"""

result = engine.analyze(scenario, world="mechaber")

# Check result
if any("min_b_mino(beef_mix)" in a for a in result["atoms"]):
    print("This is min b'mino (same species)")

if any("min_lo_batel(beef_mix)" in a for a in result["atoms"]):
    print("NOT nullified - stricter rules apply")

Noten Taam Lifgam

The Concept

Noten Taam Lifgam (gives a spoiled/bad taste) is a leniency: if the forbidden item has been altered such that it would give a bad taste, it can be nullified more easily.

Shach's Interpretation

The Shach adds conditions to bitul rules:

% interpretations/shach.lp

% Shach: Bitul doesn't apply if the issur gives noticeable taste
adds_condition(shach, r_bitul_shishim, not_noten_taam_lifgam).
makor(interpretation(shach, r_bitul_shishim), shach("yd:98:1")).

This means: even with 60:1, if the forbidden item gives noticeable (and pleasant) taste, bitul doesn't apply.

Policy Variations: Hefsed Merubeh

The Concept

Hefsed Merubeh (significant financial loss) can affect bitul calculations in some authorities' views.

Taz's Leniency

% interpretations/taz.lp

% Taz: In case of significant loss, can rely on additional leniencies
expands_scope(taz, r_bitul_shishim, hefsed_merubeh).
makor(interpretation(taz, r_bitul_shishim), taz("yd:92")).

Practical Impact

def check_bitul_with_policy(scenario, hefsed_merubeh=False):
    """Check bitul with optional hefsed_merubeh consideration."""
    engine = HsrsEngine(Path("mistaber/ontology"))

    if hefsed_merubeh:
        # Configure engine for hefsed_merubeh context
        engine.configure(
            context="hefsed_merubeh",
            policy={"hefsed_merubeh": "applies"}
        )

    result = engine.analyze(scenario, world="mechaber")
    return any("issur_batel" in a for a in result["atoms"])

World-Specific Bitul Policies

Safek Policies Affecting Bitul

When there's doubt about the ratio, safek policies determine the outcome:

World Safek D'Oraita Safek D'Rabanan
base L'chumra L'kula
ashk_mb L'chumra L'chumra (strict!)
ashk_ah L'chumra L'kula

Practical Example

def check_doubtful_ratio(world):
    """Check how doubtful bitul is handled."""
    engine = HsrsEngine(Path("mistaber/ontology"))

    scenario = """
    food(heter).
    food(issur).
    food_type(heter, parve).
    food_type(issur, basar).

    mixture(doubtful_mix).
    contains(doubtful_mix, heter).
    contains(doubtful_mix, issur).

    % Ratio is uncertain - might be 60, might not be
    safek_ratio(doubtful_mix).
    """

    result = engine.analyze(scenario, world=world)

    # The world's safek policy determines the outcome
    # ashk_mb treats safek d'rabanan l'chumra -> stricter
    # ashk_ah treats safek d'rabanan l'kula -> more lenient

# Compare worlds
for world in ["ashk_mb", "ashk_ah"]:
    check_doubtful_ratio(world)

Davar Sheyesh Lo Matirin Examples

Classic Cases

Items that will become permitted later are not nullified:

Item Why It Will Become Permitted Example
Chametz after Pesach Prohibited only during Pesach Flour mixed before Pesach
Tevel Can be tithed Untithed produce in mixture
Egg laid on Yom Tov Permitted after Yom Tov Egg that fell into food

ASP Implementation

% Define what will become permitted
will_become_permitted(F) :-
    food(F),
    status_time_limited(F),
    can_become_permitted(F).

% Chametz after Pesach
will_become_permitted(F) :-
    food(F),
    is_chametz(F),
    context(before_pesach).

% Tevel (can tithe)
will_become_permitted(F) :-
    food(F),
    is_tevel(F),
    can_tithe(F).

% Muktzeh on Shabbat (becomes permitted after)
will_become_permitted(F) :-
    food(F),
    is_muktzeh(F),
    context(shabbat).

Practical Scenario

scenario = """
food(chametz_bread).
food(matzah).

food_type(chametz_bread, grain).
food_type(matzah, grain).

is_chametz(chametz_bread).

% Before Pesach
context(before_pesach).

mixture(bread_mix).
contains(bread_mix, chametz_bread).
contains(bread_mix, matzah).

volume(matzah, 6000).
volume(chametz_bread, 10).
ratio(bread_mix, 600).  % Way more than 60:1
"""

result = engine.analyze(scenario, world="mechaber")

# Despite 600:1 ratio, chametz is NOT batel because
# it will become permitted after Pesach
if any("davar_sheyesh_lo_matirin(bread_mix)" in a for a in result["atoms"]):
    print("Chametz NOT nullified - will become permitted after Pesach")

Complete Bitul Decision Flow

                    Is it min b'mino?
                         /    \
                       Yes    No
                       /        \
              Is it noten     Is ratio >= 60:1?
              taam lifgam?        /     \
                /    \          Yes     No
              Yes    No         |        |
               |      |    Is it davar   FORBIDDEN
         Check 60:1  FORBIDDEN   sheyesh lo matirin?
               |                    /        \
          >= 60:1?                Yes        No
            /   \                  |          |
          Yes   No            FORBIDDEN    BATEL
           |     |                        (Permitted)
        BATEL  FORBIDDEN

Implementing the Decision Tree

def check_bitul(engine, mixture_name, scenario):
    """
    Complete bitul analysis following halachic decision tree.
    """
    result = engine.analyze(scenario, world="mechaber")
    atoms = result["atoms"]

    # Helper to check if atom pattern exists
    def has(pattern):
        return any(pattern in a for a in atoms)

    analysis = {
        "mixture": mixture_name,
        "is_min_b_mino": has(f"min_b_mino({mixture_name})"),
        "has_shishim": has(f"ratio({mixture_name}") and
                       any(int(a.split(",")[1].rstrip(")")) >= 60
                           for a in atoms if f"ratio({mixture_name}" in a),
        "is_davar_sheyesh_lo_matirin": has(f"davar_sheyesh_lo_matirin({mixture_name})"),
        "is_noten_taam_lifgam": has(f"noten_taam_lifgam({mixture_name})"),
        "is_batel": has(f"issur_batel({mixture_name})"),
    }

    # Determine outcome
    if analysis["is_davar_sheyesh_lo_matirin"]:
        analysis["ruling"] = "FORBIDDEN - Davar sheyesh lo matirin"
    elif analysis["is_min_b_mino"] and not analysis["is_noten_taam_lifgam"]:
        analysis["ruling"] = "FORBIDDEN - Min b'mino without pgam"
    elif not analysis["has_shishim"]:
        analysis["ruling"] = "FORBIDDEN - Less than 60:1"
    elif analysis["is_batel"]:
        analysis["ruling"] = "PERMITTED - Batel b'shishim"
    else:
        analysis["ruling"] = "CONSULT AUTHORITY"

    return analysis

Summary

This case study demonstrated:

  1. Basic bitul rule: 60:1 ratio nullifies forbidden substances
  2. Min b'mino exception: Same species requires stricter analysis
  3. Davar sheyesh lo matirin: Items that will become permitted are never nullified
  4. Noten taam lifgam: Spoiled taste can enable bitul
  5. Policy variations: Different authorities handle edge cases differently
  6. Interpretation layers: Shach and Taz modify base rules

The bitul system shows Mistaber's ability to handle: - Ratio-based calculations - Multiple conditional exceptions - Policy-dependent outcomes - Complex decision trees