Files
bikoret/shoresh-engine/src/Shoresh/Graph.hs
T
Scott KarpandClaude Sonnet 4.6 80ec364da6 Phase 1-2 build: Steps 5-6, 8-13
Shoresh Engine (Haskell, Step 5)
- 12 modules: Types, Lexicon, Binyanim, Teamim, Gematria, Graph,
  KetivQere, Smikhut, Havdalah, Kriah, KiTov, Firmware
- 33 EUnit tests, 0 failures
- Firmware module verifies L1 SHA-256 hash at startup

Talmudic Engine (SWI-Prolog, Step 6)
- 15 modules: halt, reasoning, specification, interface
- 57 PlUnit tests, 0 failures
- Three cardinal halt conditions: avodah_zarah, shfichut_damim, gilui_arayot

Vav Pipeline (Elixir, Steps 8-11)
- 14 modules: BereishitCycle, Shema, Cloud, Manna, L1Reader,
  Specification, HaltConditions, ShabbatTimer, CycleLog, Chatzotzrot,
  ShoreshEngineClient, TalmudicEngineClient, Application
- 46 ExUnit tests, 0 failures
- Nishma-first architecture: hears before it speaks

Sanhedrin Framework (Erlang/OTP, Step 12)
- 8 modules: sanhedrin_app, sanhedrin_sup, escalation, panel_sup,
  panel, judge, clerk, halt_monitor
- 46 EUnit tests, 0 failures (includes fix: rejected outcome now reachable)
- Panel sizes: 1/3/23/71 — unanimous capital guilty → acquit (Sanhedrin 17a)
- Minority opinions append-only, never deleted

Korban Processor (Python, Step 13)
- 6 modules: korban, shechitah, semichah, zerikah, haktarah, router

Builder tooling: AGENTS.md, opencode.json, memory/, src/tools/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 14:02:34 -05:00

50 lines
1.8 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
-- | Graph — root connectivity.
--
-- Architecture §3.1:
-- neighbors :: Shoresh -> ShoreshLexicon -> [ShoreshEntry]
-- "Find all roots sharing 2 consonants (semantic neighborhood)"
--
-- Two roots are neighbors if they share 2 of 3 consonants
-- in the same positions. This captures the Hebrew linguistic
-- phenomenon where related roots share consonants.
module Shoresh.Graph
( neighbors
, sharedConsonants
, neighborsByPosition
) where
import Shoresh.Types
import Shoresh.Lexicon (ShoreshLexicon, allRoots, lookupRoot)
import Data.Maybe (mapMaybe)
-- | Count shared consonants between two roots (position-sensitive).
sharedConsonants :: Shoresh -> Shoresh -> Int
sharedConsonants (Shoresh a1 b1 c1') (Shoresh a2 b2 c2') =
(if a1 == a2 then 1 else 0) +
(if b1 == b2 then 1 else 0) +
(if c1' == c2' then 1 else 0)
-- | Find all roots sharing exactly 2 consonants in the same positions.
neighbors :: Shoresh -> ShoreshLexicon -> [ShoreshEntry]
neighbors sh lexicon =
mapMaybe (\sh' ->
if sh' /= sh && sharedConsonants sh sh' >= 2
then lookupRoot sh' lexicon
else Nothing
) (allRoots lexicon)
-- | Find neighbors that share consonants at specific positions.
-- Returns (position_shared, neighbor_entry) pairs.
neighborsByPosition :: Shoresh -> ShoreshLexicon -> [(String, ShoreshEntry)]
neighborsByPosition sh@(Shoresh a b d) lexicon =
concatMap checkNeighbor (allRoots lexicon)
where
checkNeighbor sh'@(Shoresh a' b' d')
| sh' == sh = []
| a == a' && b == b' = maybe [] (\e -> [("c1c2", e)]) (lookupRoot sh' lexicon)
| a == a' && d == d' = maybe [] (\e -> [("c1c3", e)]) (lookupRoot sh' lexicon)
| b == b' && d == d' = maybe [] (\e -> [("c2c3", e)]) (lookupRoot sh' lexicon)
| otherwise = []