| |
| """ |
| Paninian Parser - Tier 2 of Vedic AI |
| Based on Ashtadhyayi's Karaka theory for unambiguous command parsing. |
| 100% deterministic - no hallucinations possible. |
| """ |
|
|
| import re |
| from dataclasses import dataclass |
| from typing import Optional, Dict, List |
| from enum import Enum |
|
|
| |
| |
| |
| class Karaka(Enum): |
| KARTR = "kartr" |
| KARMAN = "karman" |
| KARANA = "karana" |
| SAMPRAADANA = "sampraadana" |
| APAADANA = "apaadana" |
| ADHIKARANA = "adhikarana" |
|
|
| @dataclass |
| class ParsedCommand: |
| """A perfectly parsed command with zero ambiguity""" |
| action: str |
| kartr: str |
| karman: Optional[str] = None |
| karana: Optional[str] = None |
| adhikarana: Optional[str] = None |
| target_state: Optional[str] = None |
| condition: Optional[Dict] = None |
| |
| def to_executable(self) -> Dict: |
| """Convert to a deterministic executable form""" |
| return { |
| "function": self.action, |
| "params": { |
| "agent": self.kartr, |
| "patient": self.karman, |
| "instrument": self.karana, |
| "location": self.adhikarana, |
| "target": self.target_state |
| }, |
| "condition": self.condition |
| } |
|
|
| |
| |
| |
| ACTIONS = { |
| "set", "get", "start", "stop", "toggle", "increase", "decrease", |
| "open", "close", "lock", "unlock", "activate", "deactivate" |
| } |
|
|
| DEVICES = { |
| "light", "heater", "fan", "door", "window", "speaker", |
| "thermostat", "camera", "alarm", "lock", "display" |
| } |
|
|
| LOCATIONS = { |
| "living-room", "kitchen", "bedroom", "bathroom", "hall", |
| "garage", "office", "outside", "all" |
| } |
|
|
| STATES = {"on", "off", "locked", "unlocked", "open", "closed"} |
|
|
| COMPARATORS = { |
| "less-than": "<", "greater-than": ">", "equals": "==", |
| "below": "<", "above": ">", "not-equal": "!=" |
| } |
|
|
| |
| |
| |
| class PaninianParser: |
| """ |
| Implements a rule-based parser inspired by Panini's Ashtadhyayi. |
| Every sentence is decomposed into Karaka roles. |
| """ |
| |
| def __init__(self): |
| self.rules_applied = [] |
| |
| def parse(self, command: str) -> ParsedCommand: |
| """Main parse function - no ML, no probability, just rules""" |
| self.rules_applied = [] |
| command = command.lower().strip() |
| |
| |
| kartr = self._extract_kartr(command) |
| |
| |
| condition = self._extract_condition(command) |
| |
| |
| action = self._extract_action(command) |
| |
| |
| karman = self._extract_karman(command) |
| |
| |
| adhikarana = self._extract_adhikarana(command) |
| |
| |
| karana = self._extract_karana(command) |
| |
| |
| target_state = self._extract_target_state(command, action) |
| |
| return ParsedCommand( |
| action=action or "unknown", |
| kartr=kartr, |
| karman=karman, |
| karana=karana, |
| adhikarana=adhikarana, |
| target_state=target_state, |
| condition=condition |
| ) |
| |
| def _extract_kartr(self, cmd: str) -> str: |
| """Rule: Agent is before comma or 'computer'/'system'""" |
| if cmd.startswith("computer"): |
| self.rules_applied.append("Kartr: Explicit invocation 'computer'") |
| return "computer" |
| if "," in cmd: |
| before_comma = cmd.split(",")[0].strip() |
| if before_comma in ["computer", "system", "phone"]: |
| self.rules_applied.append(f"Kartr: Pre-comma designator '{before_comma}'") |
| return before_comma |
| self.rules_applied.append("Kartr: Default 'system'") |
| return "system" |
| |
| def _extract_condition(self, cmd: str) -> Optional[Dict]: |
| """Rule: 'if' clause creates a conditional""" |
| if_match = re.search(r'if\s+(\S+)\s+(less-than|greater-than|equals|below|above)\s+(\d+)', cmd) |
| if if_match: |
| self.rules_applied.append("Condition: If-clause detected") |
| return { |
| "variable": if_match.group(1), |
| "comparator": COMPARATORS.get(if_match.group(2), "=="), |
| "value": int(if_match.group(3)) |
| } |
| return None |
| |
| def _extract_action(self, cmd: str) -> Optional[str]: |
| """Rule: Action is one of the defined verbs""" |
| |
| clean_cmd = re.sub(r'if\s+.*?\d+', '', cmd) |
| |
| for action in ACTIONS: |
| if action in clean_cmd.split(): |
| self.rules_applied.append(f"Action: Found verb '{action}'") |
| return action |
| return None |
| |
| def _extract_karman(self, cmd: str) -> Optional[str]: |
| """Rule: Karman follows the action verb with 'the' or directly""" |
| for device in DEVICES: |
| |
| if f"the {device}" in cmd or re.search(rf'\b{re.escape(device)}\b', cmd): |
| self.rules_applied.append(f"Karman: Found device '{device}'") |
| return device |
| return None |
| |
| def _extract_adhikarana(self, cmd: str) -> Optional[str]: |
| """Rule: Location follows 'in' or 'at'""" |
| for loc in LOCATIONS: |
| if f"in {loc}" in cmd or f"at {loc}" in cmd: |
| self.rules_applied.append(f"Adhikarana: Location '{loc}'") |
| return loc |
| return None |
| |
| def _extract_karana(self, cmd: str) -> Optional[str]: |
| """Rule: Instrument follows 'using' or 'with'""" |
| match = re.search(r'(?:using|with)\s+(\w+(?:-\w+)?)', cmd) |
| if match: |
| self.rules_applied.append(f"Karana: Instrument '{match.group(1)}'") |
| return match.group(1) |
| return None |
| |
| def _extract_target_state(self, cmd: str, action: str) -> Optional[str]: |
| """Rule: Target state follows 'to' for set-like actions""" |
| if action in ["set", "toggle"]: |
| for state in STATES: |
| if f"to {state}" in cmd: |
| self.rules_applied.append(f"Target: State '{state}'") |
| return state |
| return None |
|
|
| |
| |
| |
| class NyayaAuditor: |
| """ |
| Formal safety auditor using Nyaya-style inference. |
| Ensures no command creates an unsafe state. |
| """ |
| |
| |
| SAFETY_RULES = [ |
| { |
| "rule": "Heater must not be on when window is open", |
| "condition": {"patient": "heater", "target": "on"}, |
| "check": {"patient": "window", "state": "open"}, |
| "violation": "Cannot turn heater on while window is open" |
| }, |
| { |
| "rule": "Door must not be locked when inside is occupied", |
| "condition": {"patient": "door", "target": "locked"}, |
| "check": {"location": "inside", "state": "occupied"}, |
| "violation": "Cannot lock door while room is occupied" |
| } |
| ] |
| |
| def __init__(self): |
| |
| self.current_state = { |
| "window": "closed", |
| "heater": "off", |
| "door": "unlocked", |
| "inside": "unoccupied", |
| "temperature": 22 |
| } |
| |
| def audit(self, parsed: ParsedCommand) -> tuple[bool, str, str]: |
| """ |
| Returns (is_safe, proof, message) |
| Uses formal syllogistic reasoning |
| """ |
| executable = parsed.to_executable() |
| |
| for rule in self.SAFETY_RULES: |
| cond = rule["condition"] |
| check = rule["check"] |
| |
| |
| if (executable["params"]["patient"] == cond["patient"] and |
| executable["params"]["target"] == cond["target"]): |
| |
| |
| state_check = check["patient"] |
| required_state = check["state"] |
| actual_state = self.current_state.get(state_check, "unknown") |
| |
| if actual_state == required_state: |
| |
| proof = ( |
| f"1. Pratijna: The command to set {cond['patient']} to {cond['target']} is unsafe.\n" |
| f"2. Hetu: Because {state_check} is {actual_state}.\n" |
| f"3. Udaharana: The rule states '{rule['rule']}'.\n" |
| f"4. Upanaya: Current {state_check} state is {actual_state}.\n" |
| f"5. Nigamana: Therefore, command violates safety rule." |
| ) |
| return False, proof, rule["violation"] |
| |
| |
| proof = ( |
| f"1. Pratijna: Command '{parsed.action} {parsed.karman}' is safe.\n" |
| f"2. Hetu: No safety rule is violated.\n" |
| f"3. Udaharana: All applicable rules checked.\n" |
| f"4. Upanaya: Current state does not conflict.\n" |
| f"5. Nigamana: Therefore, command is safe to execute." |
| ) |
| return True, proof, "Command is safe" |
|
|
| |
| |
| |
| def test_parser(): |
| parser = PaninianParser() |
| auditor = NyayaAuditor() |
| |
| test_commands = [ |
| "computer, set the heater to on in living-room", |
| "if temperature less-than 20, set the heater to on", |
| "set the light to off in kitchen", |
| "start the fan using speaker", |
| "computer, open the door", |
| "lock the door in bedroom", |
| "get temperature in living-room", |
| "toggle the light in hall", |
| ] |
| |
| print("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ") |
| print("β PANINIAN PARSER - TIER 2 VEDIC AI SHELL β") |
| print("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n") |
| |
| for i, cmd in enumerate(test_commands, 1): |
| print(f"βββ Test {i} βββ") |
| print(f"Input: \"{cmd}\"") |
| parsed = parser.parse(cmd) |
| |
| print(f"\nπ Parse Result:") |
| print(f" Kartr (Agent): {parsed.kartr}") |
| print(f" Karman (Patient): {parsed.karman}") |
| print(f" Action (Verb): {parsed.action}") |
| print(f" Adhikarana (Loc): {parsed.adhikarana}") |
| print(f" Karana (Instr): {parsed.karana}") |
| print(f" Target State: {parsed.target_state}") |
| |
| if parsed.condition: |
| print(f" Condition: IF {parsed.condition['variable']} " |
| f"{parsed.condition['comparator']} {parsed.condition['value']}") |
| |
| print(f"\nπ Rules Applied:") |
| for rule in parser.rules_applied: |
| print(f" β {rule}") |
| |
| executable = parsed.to_executable() |
| print(f"\nβοΈ Executable Form:") |
| print(f" {executable}") |
| |
| |
| is_safe, proof, msg = auditor.audit(parsed) |
| print(f"\nπ‘οΈ Safety Audit: {'β
SAFE' if is_safe else 'β UNSAFE'}") |
| print(f" {msg}") |
| print(f" Proof:\n{proof}") |
| print() |
| |
| print("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ") |
| print("β ALL PANINIAN PARSER TESTS COMPLETE β β") |
| print("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ") |
|
|
| if __name__ == "__main__": |
| test_parser() |
|
|