Understanding SocraticReasoning.py

Socratic Reasoning

understandin the ezAGI framework requires a fundamental comprehension of reasoning with SocraticReasoning.py

disclaimer: ezAGI fundamental Augmented Generative Intelligence may or not be be fun. use at own risk. breaking changes version 1

To fully audit the behavior of how the premise field is populated in the SocraticReasoning class, we will:

  1. Examine the initialization and method calls in the class.
  2. Check both programmatic and interactive ways of populating the premises.
  3. Ensure the premise field is being handled correctly in all scenarios.

SocraticReasoning.py Audit

Initialization and setup of SocraticReasoning class

class SocraticReasoning:
    def __init__(self, chatter):
        self.premises = []
        self.logger = logging.getLogger('SocraticReasoning')
        self.logger.setLevel(logging.DEBUG)  # Set to DEBUG to capture all logs
        file_handler = logging.FileHandler('./mindx/socraticlog.txt')  # Save logs to file
        file_handler.setLevel(logging.DEBUG)
        file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        file_handler.setFormatter(file_formatter)

        # Stream handler to suppress lower-level logs in the terminal
        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(logging.CRITICAL)  # Only show critical logs in the terminal
        stream_formatter = logging.Formatter('%(message)s')
        stream_handler.setFormatter(stream_formatter)

        self.logger.addHandler(file_handler)
        self.logger.addHandler(stream_handler)

        self.max_tokens = 100
        self.chatter = chatter
        self.logic_tables = LogicTables()
        self.dialogue_history = []
        self.logical_conclusion = ""

        self.premises_file = './mindx/premises.json'
        self.not_premises_file = './mindx/notpremise.json'

        create_memory_folders()  # Ensure memory folders are created
  • The __init__ method initializes the premises list, logging, and other necessary attributes.
  • create_memory_folders() ensures that the required directories are created.

Adding Premises Programmatically

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    chatter = GPT4o('your_api_key_here')  # Update with appropriate API key management
    socratic_reasoning = SocraticReasoning(chatter)

    # Example usage
    statements = [
        "Premise 1: A and B",
        "Premise 2: If A and B, then C",
        "Premise 3: Not C",
    ]

    for statement in statements:
        socratic_reasoning.add_premise(statement)

    socratic_reasoning.draw_conclusion()
    print(socratic_reasoning.logical_conclusion)
    socratic_reasoning.interact()
  • This code adds predefined premises from the statements list before the interactive session starts.
  • Each statement is passed to the add_premise method.

Adding Premises Interactively

Now, let’s look at the interactive part of the interact method:

def interact(self):
    while True:
        self.log("\nCommands: add, challenge, conclude, set_tokens, exit")
        cmd = input("> ").strip().lower()
        
        if cmd == 'exit':
            self.log('Exiting Socratic Reasoning.')
            break
        elif cmd == 'add':
            premise = input("Enter the premise: ").strip()
            self.add_premise(premise)
        elif cmd == 'challenge':
            premise = input("Enter the premise to challenge: ").strip()
            self.challenge_premise(premise)
        elif cmd == 'conclude':
            self.draw_conclusion()
        elif cmd == 'set_tokens':
            tokens = input("Enter the maximum number of tokens for the conclusion: ").strip()
            if tokens.isdigit():
                self.set_max_tokens(int(tokens))
            else:
                self.log("Invalid number of tokens.", level='error')
                self.log_not_premise("Invalid number of tokens.", level='error')
        else:
            self.log('Invalid command.', level='error')
            self.log_not_premise('Invalid command.', level='error')
  • The interact method provides an interactive command-line interface for the user.
  • For the add command, the user is prompted to enter a premise. This premise is then added using the add_premise method.

The add_premise Method

Let’s review the add_premise method to understand how premises are handled:

def add_premise(self, premise):
    if self.parse_statement(premise):
        self.premises.append(premise)
        self.log(f'Added premise: {premise}')
        self.save_premises()
    else:
        self.log(f'Invalid premise: {premise}', level='error')
        self.log_not_premise(f'Invalid premise: {premise}', level='error')
  • This method validates the premise using parse_statement.
  • If valid, it appends the premise to the self.premises list, logs the addition, and saves the premises.
  • If invalid, it logs the error and records it in the notpremise.json file.

The parse_statement Method

To understand what constitutes a valid premise, let’s review parse_statement:

  • This method checks if the statement is a non-empty string.
  • An empty string or a non-string input would be considered invalid.

Audit Summary

  1. Initialization: The SocraticReasoning class initializes with necessary attributes and creates required directories.
  2. Programmatic Premise Addition:
    • Premises are added from a predefined list before the interactive session starts.
    • The example usage in the __main__ block shows premises being added programmatically.
  3. Interactive Premise Addition:
    • The interact method provides an interface for users to add premises interactively.
    • The add command prompts the user to input a premise, which is then validated and added using the add_premise method.
  4. Validation:
    • The parse_statement method ensures that only non-empty strings are considered valid premises.
    • Invalid premises are logged and recorded in notpremise.json.

The premise field can be populated in two ways:

  • Programmatically: By adding predefined premises before the interactive session starts.
  • Interactively: By prompting the user during the interactive session.

Both methods ensure that premises are validated before being added to the self.premises list. This behavior confirms that the system handles premise input correctly, both programmatically and interactively.

The SocraticReasoning class does not send information to the prompt programmatically in the typical sense of user interaction. Instead, it programmatically adds premises directly to the premises list without user interaction before entering the interactive mode.

To clarify, the example usage in the __main__ block of the script adds premises programmatically. This means the premises are pre-defined in the code and added to the SocraticReasoning instance directly without any prompts.

relevant part of the example usage again for clarity:

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    chatter = GPT4o('your_api_key_here')  # Update with appropriate API key management
    socratic_reasoning = SocraticReasoning(chatter)

    # Example usage
    statements = [
        "Premise 1: A and B",
        "Premise 2: If A and B, then C",
        "Premise 3: Not C",
    ]

    for statement in statements:
        socratic_reasoning.add_premise(statement)

    socratic_reasoning.draw_conclusion()
    print(socratic_reasoning.logical_conclusion)
    socratic_reasoning.interact()
Explanation of Programmatic Premises
1. Initialization

    The SocraticReasoning instance is initialized with the chatter object.
    Logging is set up to capture all interactions.

2. Adding Premises Programmatically

    A list of predefined premises (statements) is created:
statements = [
    "Premise 1: A and B",
    "Premise 2: If A and B, then C",
    "Premise 3: Not C",
]

These premises are added to the SocraticReasoning instance using a loop:

for statement in statements:
    socratic_reasoning.add_premise(statement)

Each statement from the list is passed to the add_premise method:

def add_premise(self, premise):
    if self.parse_statement(premise):
        self.premises.append(premise)
        self.log(f'Added premise: {premise}')
        self.save_premises()
    else:
        self.log(f'Invalid premise: {premise}', level='error')
        self.log_not_premise(f'Invalid premise: {premise}', level='error')
  • Inside add_premise:
    • self.parse_statement(premise) checks if the premise is a valid non-empty string.
    • If valid, the premise is appended to self.premises.
    • The addition is logged, and the premises are saved to a file.
    • If invalid, an error is logged and recorded.

Drawing a Conclusion

  • After adding the premises programmatically, the draw_conclusion method is called:
socratic_reasoning.draw_conclusion() print(socratic_reasoning.logical_conclusion)

Finally, the interactive mode is started with the interact method:

socratic_reasoning.interact()
  • In this mode, the user can add new premises, challenge existing ones, draw new conclusions, set token limits, or exit the interaction.

Programmatic Premises: The premises are pre-defined in the code and added directly to the SocraticReasoning instance. There is no user prompt involved in this process. The predefined premises are:

"Premise 1: A and B",
"Premise 2: If A and B, then C",
"Premise 3: Not C"
  • Interactive Premises: During the interactive mode initiated by interact(), the user is prompted to enter premises. This interaction occurs through the console where the user inputs data.

programmatic premises: the data is predefined and added directly within the script

interactive premises: user input is added as premise, which is handled separately by the interact method

SocraticReasoning.py is a Python script designed to facilitate logical reasoning using the Socratic method. The Socratic method is a form of cooperative argumentative dialogue that stimulates critical thinking and illuminates ideas by asking and answering questions. This script provides an interactive environment where users can add premises, challenge existing premises, and draw logical conclusions based on the premises provided.

The main components of SocraticReasoning.py include:

  1. Initialization and Setup:
    • Setting up logging to capture and store logs.
    • Creating necessary memory folders for storing premises and logs.
    • Initializing attributes such as the premises list, maximum tokens, and the logical conclusion.
  2. Interactive Command-Line Interface:
    • Providing a user-friendly interface for interacting with the system.
    • Allowing users to add premises, challenge premises, draw conclusions, set token limits, and exit the interaction.
  3. Premise Management:
    • Methods for adding, challenging, and removing premises.
    • Validating premises to ensure they are logical and non-empty.
  4. Conclusion Drawing:
    • Generating logical conclusions based on the current premises.
    • Validating conclusions to ensure they are logically consistent.
  5. Logging and Memory Management:
    • Logging activities and errors for future reference.
    • Storing dialogue entries and premises for persistent memory.

To explore the first “working” instance of SocraticReasoning.py visit https://github.com/easyAGI/ezAGI

SocraticReasoning.py is a fundamental component of ezAGI the easy Augmented Generative Intelligence framework

To understand the “heart” of SocraticReasoning.py continue by exploring draw_conclusion(self)

Related articles

Chain of TRUST in LLM

https://galadriel.com/ In the realm of artificial intelligence, verifying that an AI response genuinely came from a specific model and wasn’t tampered with presents a significant challenge. The Chain of Trust in verified AI inference provides a robust solution through multiple layers of security and cryptographic proof. The Foundation: Trusted Execution Environment (TEE) At the core of verified inference lies the Trusted Execution Environment (TEE), specifically AWS Nitro Enclaves. This hardware-isolated environment provides a critical security […]

Learn More
aGLM

draw_conclusion(self)

ezAGI fundamental Augmented General Intelligence draw_conclusion(self) method The draw_conclusion method is designed to synthesize a logical conclusion from a set of premises, validate this conclusion, and then save the input/response sequence to a short-term memory storage. This function is a critical component in the context of easy Augmented General Intelligence (AGI) system, as it demonstrates the ability to process information, generate responses, validate outputs, and maintain a record of interactions for future reference and learning. […]

Learn More
RAGE

RAGE

RAGE Retrieval Augmented Generative Engine

Learn More