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:
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:
- Basic bitul rule: 60:1 ratio nullifies forbidden substances
- Min b'mino exception: Same species requires stricter analysis
- Davar sheyesh lo matirin: Items that will become permitted are never nullified
- Noten taam lifgam: Spoiled taste can enable bitul
- Policy variations: Different authorities handle edge cases differently
- 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
Related Resources¶
- Basar Bechalav Complete - Context for meat/milk bitul
- Tutorial 4: Writing Rules
- Tutorial 6: Extending Ontology