Skip to content

Case Study: Basar Bechalav Complete

A comprehensive walkthrough of Yoreh Deah Siman 87, demonstrating how Mistaber encodes the full spectrum of meat and milk prohibitions across all seven worlds.

Overview

Basar bechalav (meat and milk) is one of the foundational prohibitions in Jewish dietary law. The Torah states three times "lo tevashel gedi bachalev imo" (do not cook a kid in its mother's milk), teaching three distinct prohibitions:

  1. Bishul - Cooking meat and milk together
  2. Achiila - Eating meat and milk together
  3. Hanaah - Deriving benefit from meat and milk together

This case study demonstrates how Mistaber formally encodes these rules, handling the distinctions between different animal types and the disputes between authorities.

The Halachic Framework

Animal Categories

Category Hebrew Examples Level with Milk
Beheima בהמה Cow, sheep, goat D'oraita
Chaya ×—×™×” Deer, gazelle D'rabanan
Of עוף Chicken, turkey D'rabanan
Dag דג Fish, salmon Machloket (sakana vs mutar)

The Three Prohibitions by Category

Category Achiila Bishul Hanaah
Beheima + Chalav D'oraita D'oraita D'oraita
Chaya + Chalav D'rabanan Mutar Mutar
Of + Chalav D'rabanan Mutar Mutar
Dag + Chalav Machloket Machloket Depends

Core ASP Implementation

Mixture Detection (corpus/yd_87/base.lp)

The foundation is detecting what type of mixture we have:

% Basar types relevant to YD 87
basar_type(beheima).
basar_type(chaya).
basar_type(of).
basar_type(dag).

% A mixture contains basar if any component has a basar food type
mixture_has_basar(M, BType) :-
    mixture(M),
    contains(M, F),
    food(F),
    food_type(F, BType),
    is_basar_type(BType).

% A mixture contains chalav if any component is dairy
mixture_has_chalav(M) :-
    mixture(M),
    contains(M, F),
    food(F),
    food_type(F, chalav).

% Specific mixture classifications
is_beheima_chalav_mixture(M) :-
    mixture_has_basar(M, beheima),
    mixture_has_chalav(M).

is_of_chalav_mixture(M) :-
    mixture_has_basar(M, of),
    mixture_has_chalav(M).

is_chaya_chalav_mixture(M) :-
    mixture_has_basar(M, chaya),
    mixture_has_chalav(M).

is_dag_chalav_mixture(M) :-
    mixture_has_basar(M, dag),
    mixture_has_chalav(M).

Mechaber's Rulings (worlds/mechaber.lp)

The Mechaber encodes the Shulchan Aruch's rulings:

% YD 87:1 - BEHEIMA + CHALAV: D'ORAITA
rule(r_bb_beheima_achiila).
makor(r_bb_beheima_achiila, sa("yd:87:1")).
madrega(r_bb_beheima_achiila, d_oraita).
scope(r_bb_beheima_achiila, mechaber).

asserts(mechaber, issur(achiila, M, d_oraita)) :-
    is_beheima_chalav_mixture(M).

asserts(mechaber, issur(bishul, M, d_oraita)) :-
    is_beheima_chalav_mixture(M).

asserts(mechaber, issur(hanaah, M, d_oraita)) :-
    is_beheima_chalav_mixture(M).

% YD 87:3 - OF + CHALAV: D'RABANAN
rule(r_bb_of_achiila).
makor(r_bb_of_achiila, sa("yd:87:3")).
madrega(r_bb_of_achiila, d_rabanan).
scope(r_bb_of_achiila, mechaber).

asserts(mechaber, issur(achiila, M, d_rabanan)) :-
    is_of_chalav_mixture(M).

% Bishul and hanaah are PERMITTED for of + chalav
asserts(mechaber, heter(bishul, M)) :-
    is_of_chalav_mixture(M).

asserts(mechaber, heter(hanaah, M)) :-
    is_of_chalav_mixture(M).

% YD 87:3 - DAG + CHALAV: SAKANA (Mechaber's unique position)
rule(r_bb_dag_sakana).
makor(r_bb_dag_sakana, sa("yd:87:3")).
makor(r_bb_dag_sakana, beit_yosef("yd:87")).
scope(r_bb_dag_sakana, mechaber).

asserts(mechaber, sakana(M)) :-
    is_dag_chalav_mixture(M).

asserts(mechaber, issur(achiila, M, sakana)) :-
    is_dag_chalav_mixture(M).

Rema's Rulings with Override (worlds/rema.lp)

The Rema agrees on most points but differs on fish + dairy:

% Rema agrees on beheima, chaya, and of
% (These rules mirror mechaber's)

% YD 87:3 - DAG + CHALAV: PERMITTED (KEY DISAGREEMENT)
rule(r_rema_dag_chalav_mutar).
makor(r_rema_dag_chalav_mutar, rema("yd:87:3")).
makor(r_rema_dag_chalav_mutar, taz("yd:87:3")).
scope(r_rema_dag_chalav_mutar, rema).

% Override the sakana ruling from Mechaber
override(rema, sakana(M), no_sakana) :-
    is_dag_chalav_mixture(M).

override(rema, issur(achiila, M, sakana), permitted) :-
    is_dag_chalav_mixture(M).

% Explicitly assert permission
asserts(rema, heter(achiila, M)) :-
    is_dag_chalav_mixture(M).

asserts(rema, no_sakana(M)) :-
    is_dag_chalav_mixture(M).

% Mark the machloket
machloket(dag_chalav, mechaber, rema, M) :-
    is_dag_chalav_mixture(M).

Running the Complete Analysis

Test Scenario: Multiple Mixtures

from pathlib import Path
from mistaber.engine import HsrsEngine

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

scenario = """
% === Define foods ===
food(beef).        food_type(beef, beheima).
food(chicken).     food_type(chicken, of).
food(venison).     food_type(venison, chaya).
food(salmon).      food_type(salmon, dag).
food(milk).        food_type(milk, chalav).

% === Create mixtures ===
mixture(beef_milk).
contains(beef_milk, beef).
contains(beef_milk, milk).

mixture(chicken_milk).
contains(chicken_milk, chicken).
contains(chicken_milk, milk).

mixture(venison_milk).
contains(venison_milk, venison).
contains(venison_milk, milk).

mixture(salmon_milk).
contains(salmon_milk, salmon).
contains(salmon_milk, milk).
"""

# Analyze each mixture in both worlds
for world in ["mechaber", "rema"]:
    result = engine.analyze(scenario, world=world)
    print(f"\n=== {world.upper()} ===")

    for mixture in ["beef_milk", "chicken_milk", "venison_milk", "salmon_milk"]:
        issurim = [a for a in result["atoms"]
                   if mixture in a and ("issur" in a or "heter" in a or "sakana" in a)]
        print(f"\n{mixture}:")
        for i in issurim:
            print(f"  {i}")

Expected Output

=== MECHABER ===

beef_milk:
  holds(issur(achiila,beef_milk,d_oraita),mechaber)
  holds(issur(bishul,beef_milk,d_oraita),mechaber)
  holds(issur(hanaah,beef_milk,d_oraita),mechaber)

chicken_milk:
  holds(issur(achiila,chicken_milk,d_rabanan),mechaber)
  holds(heter(bishul,chicken_milk),mechaber)
  holds(heter(hanaah,chicken_milk),mechaber)

venison_milk:
  holds(issur(achiila,venison_milk,d_rabanan),mechaber)
  holds(heter(bishul,venison_milk),mechaber)
  holds(heter(hanaah,venison_milk),mechaber)

salmon_milk:
  holds(sakana(salmon_milk),mechaber)
  holds(issur(achiila,salmon_milk,sakana),mechaber)

=== REMA ===

beef_milk:
  holds(issur(achiila,beef_milk,d_oraita),rema)
  holds(issur(bishul,beef_milk,d_oraita),rema)
  holds(issur(hanaah,beef_milk,d_oraita),rema)

chicken_milk:
  holds(issur(achiila,chicken_milk,d_rabanan),rema)
  holds(heter(bishul,chicken_milk),rema)
  holds(heter(hanaah,chicken_milk),rema)

venison_milk:
  holds(issur(achiila,venison_milk,d_rabanan),rema)
  holds(heter(bishul,venison_milk),rema)
  holds(heter(hanaah,venison_milk),rema)

salmon_milk:
  holds(heter(achiila,salmon_milk),rema)
  holds(heter(bishul,salmon_milk),rema)
  holds(no_sakana(salmon_milk),rema)

Tier 3 Worlds Inheritance

The Tier 3 worlds (ashk_mb, ashk_ah, sefardi_yo) inherit from their respective Tier 2 parents:

Sefardi Yalkut Yosef

% sefardi_yo inherits from mechaber
accessible(sefardi_yo, mechaber).

% Therefore:
% - Beheima+chalav: d'oraita (inherited)
% - Of+chalav: d'rabanan for achiila, mutar for bishul/hanaah (inherited)
% - Dag+chalav: SAKANA (inherited from mechaber)

Ashkenazi Mishnah Berurah

% ashk_mb inherits from rema
accessible(ashk_mb, rema).

% Therefore:
% - Beheima+chalav: d'oraita (inherited)
% - Of+chalav: d'rabanan for achiila, mutar for bishul/hanaah (inherited)
% - Dag+chalav: MUTAR (inherited via rema's override)

Ashkenazi Aruch Hashulchan

% ashk_ah inherits from BOTH rema AND gra
accessible(ashk_ah, rema).
accessible(ashk_ah, gra).

% Multiple inheritance - both parents agree on dag+chalav: mutar
% If they disagreed, would need explicit resolution

Comparing All Seven Worlds

from pathlib import Path
from mistaber.engine import HsrsEngine

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

# Fish + dairy scenario
scenario = """
food(fish). food_type(fish, dag).
food(cream). food_type(cream, chalav).
mixture(fish_cream).
contains(fish_cream, fish).
contains(fish_cream, cream).
"""

all_worlds = ["base", "mechaber", "rema", "gra", "sefardi_yo", "ashk_mb", "ashk_ah"]

print("Fish + Dairy Status by World:")
print("=" * 50)

for world in all_worlds:
    result = engine.analyze(scenario, world=world)
    atoms = result["atoms"]

    has_sakana = any("sakana(fish_cream)" in a for a in atoms)
    has_issur = any("issur(achiila,fish_cream" in a for a in atoms)
    has_heter = any("heter(achiila,fish_cream)" in a for a in atoms)

    if has_sakana:
        status = "FORBIDDEN (sakana)"
    elif has_issur:
        status = "FORBIDDEN (issur)"
    elif has_heter:
        status = "PERMITTED"
    else:
        status = "No ruling derived"

    print(f"{world:15} -> {status}")

Expected Output

Fish + Dairy Status by World:
==================================================
base            -> No ruling derived
mechaber        -> FORBIDDEN (sakana)
rema            -> PERMITTED
gra             -> PERMITTED
sefardi_yo      -> FORBIDDEN (sakana)
ashk_mb         -> PERMITTED
ashk_ah         -> PERMITTED

Source Citations (Makor)

Every rule has traceable sources:

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

# Query all makor citations for YD 87 rules
makorot = engine.query("makor(Rule, Source)")

print("Source citations in basar bechalav rules:")
for m in makorot:
    if "bb" in m.get("Rule", "").lower() or "87" in str(m.get("Source", "")):
        print(f"  {m['Rule']}: {m['Source']}")

Sample Output

Source citations in basar bechalav rules:
  r_bb_beheima_achiila: sa("yd:87:1")
  r_bb_beheima_bishul: sa("yd:87:1")
  r_bb_of_achiila: sa("yd:87:3")
  r_bb_dag_sakana: sa("yd:87:3")
  r_bb_dag_sakana: beit_yosef("yd:87")
  r_rema_dag_chalav_mutar: rema("yd:87:3")
  r_rema_dag_chalav_mutar: taz("yd:87:3")

Practical Applications

Application 1: Restaurant Compliance

A restaurant wants to know if a dish is compliant for both Ashkenazi and Sefardi customers:

def check_compliance(mixture_scenario, target_worlds):
    """Check if a dish is compliant across multiple traditions."""
    engine = HsrsEngine(Path("mistaber/ontology"))

    compliance = {}
    for world in target_worlds:
        result = engine.analyze(mixture_scenario, world=world)
        atoms = result["atoms"]

        has_issur = any("issur(" in a for a in atoms)
        has_sakana = any("sakana(" in a for a in atoms)

        compliance[world] = not (has_issur or has_sakana)

    return compliance

# Check lox and cream cheese
scenario = """
food(salmon). food_type(salmon, dag).
food(cream_cheese). food_type(cream_cheese, chalav).
mixture(lox_cream_cheese).
contains(lox_cream_cheese, salmon).
contains(lox_cream_cheese, cream_cheese).
"""

result = check_compliance(scenario, ["sefardi_yo", "ashk_mb"])
print(f"Lox & cream cheese compliance:")
print(f"  Sefardi (Yalkut Yosef): {'OK' if result['sefardi_yo'] else 'NOT OK'}")
print(f"  Ashkenazi (Mishnah Berurah): {'OK' if result['ashk_mb'] else 'NOT OK'}")

Application 2: Educational Tool

Generate a comparison table for teaching:

def generate_comparison_table():
    """Generate a teaching comparison table."""
    engine = HsrsEngine(Path("mistaber/ontology"))

    mixtures = {
        "beef_milk": ("beheima", "chalav"),
        "chicken_milk": ("of", "chalav"),
        "fish_milk": ("dag", "chalav"),
    }

    for mix_name, (basar, dairy) in mixtures.items():
        scenario = f"""
        food({basar}_item). food_type({basar}_item, {basar}).
        food({dairy}_item). food_type({dairy}_item, {dairy}).
        mixture({mix_name}).
        contains({mix_name}, {basar}_item).
        contains({mix_name}, {dairy}_item).
        """

        print(f"\n{mix_name.upper().replace('_', ' + ')}:")
        for world in ["mechaber", "rema"]:
            result = engine.analyze(scenario, world=world)
            # Extract and display ruling...

Summary

This case study demonstrated:

  1. Mixture Detection: How ASP rules classify mixtures by component types
  2. World-Specific Rules: How different authorities encode their rulings
  3. Override Mechanism: How Rema's disagreement blocks inheritance
  4. Inheritance Chain: How Tier 3 worlds inherit from Tier 2
  5. Practical Queries: How to check compliance across traditions
  6. Source Traceability: Every rule maps back to its textual source

The basar bechalav encoding shows Mistaber's power: formally encoding complex, multi-layered halachic reasoning while preserving the authentic structure of rabbinic discourse.