Skip to content

HLL (Halachic Logic Language) Reference

Overview

HLL is a domain-specific language for expressing halachic rules in a formal, machine-readable format. It compiles to Answer Set Programming (ASP) for execution by the Clingo solver within the Mistaber reasoning engine.

Grammar Structure

The HLL grammar is defined in mistaber/dsl/grammar.lark:

program     := (directive | rule | fact)*
directive   := world_directive | rule_directive | makor_directive | madrega_directive
rule        := head ":-" body "."
fact        := head "."

Directives

Directives are metadata annotations that provide context for rules.

@world(identifier)

Specifies the modal world/context for subsequent rules.

@world(base)              % Default world
@world(rema)              % Rema's opinion
@world(mechaber)          % Mechaber's opinion

Usage: Enables multi-world semantics for representing machloket (disputes).

@rule(identifier)

Assigns a unique identifier to a rule for traceability and debugging.

@rule(r_basar_bechalav_issur)
@rule(r_gevinas_akum)

Best Practice: Use descriptive names with r_ prefix.

@makor([source_list])

MANDATORY for normative rules. Cites halachic sources.

@makor([sa("Yoreh Deah 87:1")])
@makor([sa("YD:87:1"), rambam("Maachalot Asurot 9:1")])
@makor([mishnah("Chullin 8:1"), gemara("Chullin 103b")])

Source Types: | Type | Full Name | Example | |------|-----------|---------| | sa | Shulchan Aruch | sa("YD:87:1") | | rambam | Mishneh Torah | rambam("Maachalot Asurot 9:1") | | tur | Arba'ah Turim | tur("YD:87") | | mishnah | Mishnah | mishnah("Chullin 8:1") | | gemara | Talmud Bavli | gemara("Chullin 103b") | | tosefta | Tosefta | tosefta("Chullin 8:3") | | beit_yosef | Beit Yosef | beit_yosef("yd:87") |

@madrega(level)

Specifies the obligation level of the rule.

@madrega(d_oraita)    % Biblical
@madrega(d_rabanan)   % Rabbinic
@madrega(minhag)      % Custom
@madrega(chumra)      % Stringency

Strength Ordering: d_oraita > d_rabanan > minhag > chumra

Facts

Facts are unconditional statements about the world.

% Simple facts
is_food(chicken).
vessel(pot1).
mixture(m1).

% Facts with arguments
food_type(chicken, basar).
food_type(milk, chalav).
contains(m1, chicken).
contains(m1, milk).

% Classification facts
madrega(r_basar_bechalav, d_oraita).

Rules

Rules define logical implications.

% Basic rule
head :- body.

% Rule with multiple conditions (AND)
forbidden(W, achiila, M, ctx_normal) :-
    mixture(M),
    mixture_contains_basar(M),
    mixture_contains_chalav(M).

% Rule with negation
permitted(W, achiila, F, ctx_normal) :-
    food(F),
    food_type(F, parve),
    not has_issur(F).

Negation

Use not prefix for negation-as-failure:

% Permitted if not explicitly forbidden
permitted(W, A, F, C) :-
    food(F),
    not forbidden(W, A, F, C).

% Classification when not classified
classification_unknown(F) :-
    food(F),
    not food_type(F, basar),
    not food_type(F, chalav),
    not food_type(F, parve).

Warning: Negating OWA predicates generates a compiler warning.

Data Types

Identifiers (Constants)

Lowercase identifiers represent constants:

chicken         % Food item
basar           % Category
achiila         % Action type
ctx_normal      % Context
d_oraita        % Madrega level

Variables

Uppercase identifiers represent variables (bind to any value):

Food            % Any food
W               % Any world
M               % Any mixture
Category        % Any category

Strings

Quoted text for source references and descriptions:

"Yoreh Deah 87:1"
"Rambam Hilchot Maachalot Asurot"

Numbers

Integer literals:

60              % Bitul ratio
24              % Hours for kavush
45              % Yad soledet temperature

Compound Terms

Nested function-like structures:

sa("YD:87:1")
rambam("Maachalot Asurot 9:1")
ratio(m1, 60)

Surface Syntax (Shortcuts)

HLL provides Hebrew-inspired shortcuts that normalize to canonical predicates.

Food Type Shortcuts

Shortcut Expands To
basar(X) food_type(X, basar)
chalav(X) food_type(X, chalav)
parve(X) food_type(X, parve)
beheima(X) food_type(X, beheima)
chaya(X) food_type(X, chaya)
of(X) food_type(X, of)
dag(X) food_type(X, dag)
mashkeh(X) food_type(X, mashkeh)
tavlin(X) food_type(X, tavlin)

Example:

% Surface syntax
basar(chicken).
chalav(milk).

% Normalizes to
food_type(chicken, basar).
food_type(milk, chalav).

Status Shortcuts

Shortcut Expands To
issur(A, F) forbidden(W, A, F, ctx_normal)
mutar(A, F) permitted(W, A, F, ctx_normal)

Example:

% Surface syntax
issur(achiila, treif_meat).

% Normalizes to (W from @world or variable)
forbidden(base, achiila, treif_meat, ctx_normal).

Comments

Line comments start with %:

% This is a comment
is_food(chicken).  % Inline comment

% Multi-line comments use multiple %
% Line 1
% Line 2

Complete Example

% =============================================================
% Basar B'Chalav (Meat and Milk) - Basic Prohibition
% =============================================================

@world(base)
@rule(r_basar_bechalav_issur)
@makor([sa("Yoreh Deah 87:1"), rambam("Maachalot Asurot 9:1")])
@madrega(d_oraita)

% === Food Declarations ===
is_food(beef).
is_food(chicken).
is_food(milk).
is_food(butter).
is_food(carrot).

% === Food Classifications ===
food_type(beef, beheima).      % Domesticated land animal
food_type(chicken, of).         % Bird
food_type(milk, chalav).        % Dairy
food_type(butter, chalav).      % Dairy
food_type(carrot, parve).       % Neutral

% === Mixture Declaration ===
mixture(beef_milk_stew).
contains(beef_milk_stew, beef).
contains(beef_milk_stew, milk).

% === Prohibition Rule ===
% Eating a mixture of meat and milk is forbidden
forbidden(W, achiila, M, ctx_normal) :-
    world(W),
    mixture(M),
    mixture_is_basar_bechalav(M).

% === Benefit Prohibition ===
% Deriving benefit from basar b'chalav is also forbidden
forbidden(W, hanaah, M, ctx_normal) :-
    world(W),
    mixture(M),
    mixture_is_basar_bechalav(M).

% === Permission for Parve ===
% Parve foods are permitted
permitted(W, achiila, F, ctx_normal) :-
    world(W),
    food(F),
    food_type(F, parve),
    not has_issur(F).

Type System

Normative Predicates

These predicates make halachic determinations:

Predicate Arity Description
forbidden(world, action, food, context) 4 Action on food is prohibited
permitted(world, action, food, context) 4 Action on food is allowed
safek(food) 1 Food has doubtful status

Requirement: All normative predicates require @makor directive.

Classification Predicates

Predicate Arity Description
is_food(food) 1 Entity is a food item
food_type(food, category) 2 Food belongs to category
food_cat(food, category) 2 Alias for food_type
mixture(mixture) 1 Entity is a mixture
contains(mixture, food) 2 Mixture contains food
vessel(vessel) 1 Entity is a vessel

Enumerated Values

Food Categories: maakhal, basar, chalav, parve, beheima, chaya, of, dag, mashkeh, tavlin

Action Types: achiila (eating), bishul (cooking), hanaah (benefit)

Contexts: ctx_normal, ctx_hefsed, ctx_shaat_hadchak

Madrega Levels: d_oraita, d_rabanan, minhag, chumra

Error Messages

Parse Errors

ParseError: Parse error at line 5, column 12: Unexpected token

Common Causes: - Missing period at end of fact/rule - Unbalanced parentheses - Invalid identifier (starting with uppercase when constant expected)

Normalization Errors

NormalizationError: issur() expects exactly 2 arguments, got 1

Common Causes: - Wrong arity for surface syntax predicates - Using undefined shortcuts

Type Check Errors

TypeCheckError: Undeclared predicate: unknwon_pred/2
TypeCheckError: Arity mismatch for food_type: expected 2, got 3
TypeCheckError: Missing @makor directive for normative rule with head: forbidden

Common Causes: - Typo in predicate name - Wrong number of arguments - Missing required directive for normative rules

Type Check Warnings

TypeCheckWarning: Using negation with OWA predicate 'permitted' may cause unsafe permissiveness

Meaning: Negating an open-world predicate can lead to unintended conclusions.

Best Practices

  1. Always use @makor: Cite sources for all normative rules
  2. Use descriptive rule IDs: r_basar_bechalav_issur not r1
  3. Group related facts: Organize by entity type
  4. Comment complex rules: Explain halachic reasoning
  5. Use surface syntax: basar(X) is clearer than food_type(X, basar)
  6. Test incrementally: Compile and test small changes
  7. Avoid OWA negation: Prefer explicit positive conditions