File size: 8,358 Bytes
f054e62
 
 
 
 
 
 
 
 
 
 
71fa3d9
f054e62
 
 
 
71fa3d9
 
f054e62
71fa3d9
 
 
 
 
5ed8a97
a49d431
5ed8a97
71fa3d9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f054e62
 
 
 
71fa3d9
 
f054e62
 
 
 
71fa3d9
f054e62
 
71fa3d9
f054e62
71fa3d9
f054e62
 
 
 
71fa3d9
f054e62
 
 
 
71fa3d9
f054e62
 
71fa3d9
f054e62
71fa3d9
 
f054e62
 
 
 
 
 
71fa3d9
f054e62
 
 
 
 
 
71fa3d9
f054e62
 
 
 
 
 
 
 
71fa3d9
 
c52408e
 
f054e62
71fa3d9
c52408e
 
 
 
71fa3d9
 
 
 
a8e06c6
 
71fa3d9
a8e06c6
 
 
 
71fa3d9
a8e06c6
 
 
71fa3d9
 
 
 
a8e06c6
 
71fa3d9
a8e06c6
 
 
 
71fa3d9
 
 
 
 
c52408e
71fa3d9
a49d431
c52408e
71fa3d9
 
c52408e
71fa3d9
c52408e
71fa3d9
c52408e
71fa3d9
 
 
 
f054e62
 
71fa3d9
f054e62
 
71fa3d9
 
 
 
 
 
f054e62
5ed8a97
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import json
import logging
import argparse
import sys
import os
import math
import pickle
from deep_translator import GoogleTranslator
from gematria import calculate_gematria
from collections import defaultdict

# --- Configuration ---
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
BOOK_RANGE = range(1, 40)
CACHE_FILE = "tanakh_phrasedict.cache"

# --- Core Functions ---

def get_power_result(total_sum, query_value):
    """
    Calculates the power or root result.
    - If query_value <= total_sum, it finds the highest power of query_value that is <= total_sum.
    - If query_value > total_sum, it finds the smallest n-th root of query_value whose result is <= total_sum.
    """
    if total_sum <= 0 or query_value <= 1:
        return 1

    # Normal case: "Power Mode"
    if query_value <= total_sum:
        try:
            exponent = int(math.floor(math.log(total_sum, query_value)))
            return query_value ** exponent
        except (ValueError, OverflowError):
            return 1

    # Special case: "Root Mode"
    else:  # query_value > total_sum
        # Find the smallest integer root 'n' (starting from 2)
        # that reduces query_value to a number <= total_sum.
        for n in range(2, 65):  # Limit the search to a reasonable range (up to the 64th root)
            try:
                root_result = query_value ** (1.0 / n)
                if root_result <= total_sum:
                    # We found the smallest root exponent n.
                    # Round up and return as an integer.
                    return math.ceil(root_result)
            except (ValueError, OverflowError):
                # Catches math errors with extreme numbers
                return 1

        # If even the 64th root is too large, which only happens with
        # extreme number ratios, return a default value.
        return 1

def load_phrase_dictionary():
    if not os.path.exists(CACHE_FILE):
        sys.exit(f"ERROR: Cache file '{CACHE_FILE}' not found. Please run 'build_indices.py' first to create the index.")
    logging.info(f"Loading phrase dictionary from cache: {CACHE_FILE}")
    try:
        with open(CACHE_FILE, 'rb') as f:
            return pickle.load(f)
    except Exception as e:
        sys.exit(f"ERROR: Cache file '{CACHE_FILE}' is corrupt. Please delete it and run 'build_indices.py' again. Error: {e}")

def find_all_matching_phrases(target_sum, phrase_dictionary):
    return phrase_dictionary.get(int(target_sum), [])

# --- Main Program ---
def main(args):
    phrase_dictionary = load_phrase_dictionary()
    query_value = calculate_gematria(args.query)
    if query_value <= 1:
        sys.exit(f"ERROR: Query '{args.query}' has an invalid Gematria value ({query_value}).")

    translator = None
    if args.translate:
        try:
            # The correct code for Hebrew is 'iw'
            translator = GoogleTranslator(source='iw', target='en')
        except Exception as e:
            logging.error(f"Could not initialize translator: {e}")

    logging.info(f"Starting oracle analysis for '{args.query}' (G:{query_value}) with bitplane variation depth {args.xor_depth}...")
    print("\n" + "="*20 + f" ORACLE ANSWERS FOR '{args.query}' " + "="*20)

    verses_processed = 0
    resonance_count = 0

    for book_num in BOOK_RANGE:
        if args.process_verses and verses_processed >= args.process_verses: break

        filepath = f"texts/torah/{book_num:02}.json"
        try:
            with open(filepath, 'r', encoding='utf-8') as file:
                data = json.load(file)
                for chap_idx, chapter in enumerate(data.get("text", []), start=1):
                    if args.process_verses and verses_processed >= args.process_verses: break

                    for verse_idx, verse_text in enumerate(chapter, start=1):
                        if args.process_verses and verses_processed >= args.process_verses: break
                        verses_processed += 1

                        verse_sum = calculate_gematria(verse_text)
                        if verse_sum <= 1: continue

                        power_result = get_power_result(verse_sum, query_value)

                        # Calculate the main result first
                        main_target_sum = verse_sum ^ power_result
                        main_matches = find_all_matching_phrases(main_target_sum, phrase_dictionary)

                        # Only proceed if a main resonance exists
                        if not main_matches:
                            continue

                        resonance_count += 1
                        verse_ref = f"B{book_num:02d}, C{chap_idx}, V{verse_idx}"
                        print(f"\n--- Resonance #{resonance_count} in [{verse_ref}] (G_sum:{verse_sum}) ---")
                        print(f"Original Verse: {verse_text.strip()}")

                        def print_matches(matches, title, calculation_str):
                            if not matches: return

                            matches.sort(key=lambda p: (p.get('freq', 0) / p.get('words', 99)), reverse=True)
                            matches_to_show = matches[:args.results_per_verse]

                            print(f"  ↳ {title}: {calculation_str}")

                            for match in matches_to_show:
                                translation_str = ""
                                if translator:
                                    try:
                                        translation_str = translator.translate(match['text'])
                                    except Exception:
                                        translation_str = "[Translation failed]"

                                score = (match.get('freq', 0) / match.get('words', 99))
                                info = f"(Words: {match.get('words', 'N/A')}, Freq: {match.get('freq', 'N/A')}, Score: {score:.2f})"
                                print(f"     - {match['text']} {info}")
                                if translation_str:
                                    print(f"       ↳ Interpretation: \"{translation_str}\"")

                        # 1. Display the main resonance
                        calc_str = f"[{verse_sum}] ^ [{power_result}] β†’ [G_target:{main_target_sum}]"
                        print_matches(main_matches, "Main Resonance", calc_str)

                        # 2. Display the bitplane variations of the RESULT
                        if args.xor_depth > 0:
                            print(f"   [INFO] Bitplane Variations of the Result ({main_target_sum}):")
                            for depth in range(args.xor_depth):
                                bit_flip = 1 << depth

                                # Flip the 'd'-th bit in the main result
                                target_sum = main_target_sum ^ bit_flip

                                bitplane_matches = find_all_matching_phrases(target_sum, phrase_dictionary)

                                if bitplane_matches:
                                    # FIX: The label is now depth + 1 for human readability
                                    bitplane_calc_str = f"[{main_target_sum}] ^ [Bit {depth+1}] β†’ [G_target:{target_sum}]"
                                    print_matches(bitplane_matches, f"Variation (Depth {depth + 1})", bitplane_calc_str)

        except FileNotFoundError: continue

    logging.info(f"Analysis complete. Found {resonance_count} resonance groups in {verses_processed} analyzed verses.")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Tanakh Universal Resonance Analyzer with Bitplane Variations.")
    parser.add_argument("query", type=str, help="The query phrase (e.g., 'Χ™Χ”Χ•Χ”').")
    parser.add_argument("--translate", action="store_true", default=True, help="Enable automatic translation of results to English.")
    parser.add_argument("--process-verses", type=int, default=10, help="Maximum number of starting verses to analyze.")
    parser.add_argument("--results-per-verse", type=int, default=1, help="Maximum oracle answers to show per resonance type (default: 3).")
    parser.add_argument("--xor-depth", type=int, default=2, help="Maximum depth for bitplane variations of the result (0-15) (default: 16).")
    args = parser.parse_args()
    main(args)