Spaces:
Sleeping
Sleeping
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) | |