File size: 5,537 Bytes
f054e62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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)