import json import logging import argparse import sys import os import re import math from gematria import calculate_gematria # --- Konfiguration --- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') BOOK_RANGE = range(1, 40) INDICES_DIR = "indices_by_book" # --- Kernfunktionen --- def xor_with_highest_power(total_sum, query_value): """Ihre XOR-Logik.""" if total_sum <= 0 or query_value <= 1: return None if query_value > total_sum: power = 1 else: exponent = math.floor(math.log(total_sum, query_value)) power = query_value ** exponent return total_sum ^ power def prepare_phrase_inventory(all_indices): """ Erstellt eine flache, aber als Dictionary organisierte Liste aller Phrasen für schnelle Abfragen. Struktur: { gematria_value: [phrase_obj_1, phrase_obj_2, ...], ... } """ logging.info("Erstelle ein optimiertes Inventar aller Phrasen...") inventory = {} for book_num, index in all_indices.items(): for gematria_val_str, data in index.items(): gematria_val = int(gematria_val_str) if gematria_val not in inventory: inventory[gematria_val] = [] pagerank = data.get('pagerank', 0) for phrase_data in data.get('phrases', []): count = phrase_data.get('count', 1) score = pagerank / count if count > 0 else 0 inventory[gematria_val].append({ "text": phrase_data['text'], "score": score, "source_book": book_num }) # Sortiere die Phrasenlisten innerhalb jedes Eintrags nach Score for gematria_val in inventory: inventory[gematria_val].sort(key=lambda x: x['score'], reverse=True) logging.info(f"{len(inventory)} einzigartige Gematria-Werte im Inventar.") return inventory def find_best_phrase(target_sum, inventory): """Findet die eine, beste Phrase für eine gegebene Summe.""" if target_sum in inventory: # Gibt die Phrase mit dem höchsten Score zurück (da die Liste vorsortiert ist) return inventory[target_sum][0] return None # --- Hauptprogramm --- def main(args): # Lade alle Indizes all_indices = {} for i in BOOK_RANGE: index_path = os.path.join(INDICES_DIR, f"book_{i:02}_index.json") if os.path.exists(index_path): with open(index_path, 'r', encoding='utf-8') as f: all_indices[i] = json.load(f) if not all_indices: sys.exit("Keine Index-Dateien gefunden. Bitte 'build_indices.py' ausführen.") # 1. Bereite das Phrasen-Inventar für schnelle Abfragen vor phrase_inventory = prepare_phrase_inventory(all_indices) # 2. Berechne Gematria-Wert der Anfrage query_value = calculate_gematria(args.query) if query_value <= 1: sys.exit(f"Anfrage '{args.query}' hat einen ungültigen Gematria-Wert ({query_value}). Wert muss > 1 sein.") # 3. Iteriere durch jeden Vers des Tanach logging.info(f"Starte Vers-Resonanz-Analyse für '{args.query}' (Gematria: {query_value})...") print("\n" + "="*15 + f" ERGEBNISSE DER VERS-RESONANZ-ANALYSE FÜR '{args.query}' " + "="*15) resonance_count = 0 verses_processed = 0 for book_num in BOOK_RANGE: try: with open(f"texts/torah/{book_num:02}.json", 'r', encoding='utf-8') as file: data = json.load(file) # Iteriere durch Kapitel und Verse for chap_idx, chapter in enumerate(data.get("text", [])): for verse_idx, verse in enumerate(chapter): verses_processed += 1 # Berechne Gematria-Summe des Verses verse_sum = calculate_gematria(verse) if verse_sum <= 1: continue # Führe die XOR-Operation durch target_sum = xor_with_highest_power(verse_sum, query_value) if target_sum is None: continue # Finde die beste Resonanz-Phrase best_match = find_best_phrase(target_sum, phrase_inventory) # Gib das Ergebnis aus, wenn eine Resonanz gefunden wurde if best_match: resonance_count += 1 verse_ref = f"Buch {book_num:02}, Kap. {chap_idx+1}, Vers {verse_idx+1}" print(f"\n--- Resonanz gefunden in: {verse_ref} ---") print(f"Originalvers (G: {verse_sum}): {verse}") print(f"XOR-Resultat (Ziel-G: {target_sum}): {best_match['text']} (aus B{best_match['source_book']:02d})") if resonance_count >= args.limit: logging.info(f"Ausgabelimit von {args.limit} Resonanzen erreicht. Beende Analyse.") return except FileNotFoundError: continue logging.info(f"Analyse abgeschlossen. {resonance_count} Resonanzen in {verses_processed} Versen gefunden.") if __name__ == "__main__": parser = argparse.ArgumentParser(description="Tanakh Verse Resonance Analyzer.") parser.add_argument("query", type=str, help="Die Abfragephrase (z.B. 'יהוה').") parser.add_argument("--limit", type=int, default=25, help="Maximale Anzahl der auszugebenden Resonanzen.") args = parser.parse_args() main(args)