import re
from .ensure_answer_consistent_grammar import ensure_answer_consistent_grammar
from llama_cpp import Llama
from .constants import LOGICAL_MODEL

# Answer vetting
# For now, this checks answer relevancy too. The danger with abstracting answer relevancy into a separate step is that anything which relies on knowledge that is obviously mentioned in the text already up until this point, will get screwed
def ensure_answer_consistent(qatuple, conv, logic_llm, permissive_mode=True):
    """
    permissive_mode: turn off if you want a single usage of the word "inconsistent" anywhere in the message to flag the whole thing as inconsistent. Prevents errors where an inconsistency happens way early in the answer, but the model forgets about it during its final judgement; but enables the error where the model mentions that something is "not entirely inconsistent" or similar, which is surprisingly common.
    """
    retries = 0

    # It's expensive to regen a conversation; so we check very thoroughly, and use a two-shot example. "Permissive mode" recommended

    # NOTE: I don't know what kind of errors this part of the pipeline will run into most often, so I don't really know what examples to feed it to guard it with. Come back to it once I have tested it more.
    while retries <= 4:
        decision_prompt = f"""You are an expert educational AI. Your task is to determine whether two answers are the same, given a question, its answer, and a conversation between two fictional individuals in which that question is asked and that answer is provided. You will also check whether the question is essentially the same, and does not go "off the rails". Essentially: you will fact-check and consistency-check the question and answer in the conversation, with your source of truth being the provided question and answer.

Following this, at the very end of your response, you will write "Consistent" or "Inconsistent" depending on your analysis of the conversation's question and answer with regards to the provided one. Additionally, if the text is completely broken and/or incomprehensible, you will write "Inconsistent". You are not checking the accuracy of the answer, just its consistency with the provided answer.

You should analyze the conversation piece-by-piece to ensure that the question and answer both are faithfully carried over. Make determine the consistency of each piece, then state your final determination at the end.

Work step-by-step.

### Instruction:
Provided Question: Why is the sky blue?
Provided Answer: The Earth's atmosphere scatters the shorter blue wavelengths of light from the sun more than other colors, giving the sky a blue color during the day.

Conversation:
\"\"\"
Bob: "Hey Dave!" I smile. "I gotta know, since you're a meteorologist: Do you know why the sky is blue? I made a bet with a friend that you know, help me out here."
Dave: "Sure, Bob!" I assume a matter-of-fact tone. "The sky is blue because the Earth's atmosphere scatters the shorter wavelengths of sunlight more than the others. This means that the blue wavelengths, which are shorter, are scattered widely, causing the sky to appear blue to us on the ground."
\"\"\"

### Response:
## Reasoning and thought process:
Step 1. Understand the provided question: The question is straightforward and asks about the reason for the sky's blue color.
Step 2. Compare the conversation's question: the conversation's question is, "Do you know why the sky is blue?" compared to the provided question, "Why is the sky blue?" Although the conversation's question includes additional context, the core question remains unchanged, so this part is "consistent".
Step 3. Understand the provided answer: the provided answer is "The Earth's atmosphere scatters the shorter blue wavelengths of light from the sun more than other colors, giving the sky a blue color during the day." I will now compare this with the conversation's answer.
Step 4. Compare the conversation's answer: Dave's response in the conversation is "The sky is blue because the Earth's atmosphere scatters the shorter wavelengths of sunlight more than the others. This means that the blue wavelengths, which are shorter, are scattered widely, causing the sky to appear blue to us on the ground." This explanation aligns closely with the provided answer, so this part is "consistent".
Step 5. Final judgement: Consistent.

### Instruction:
Provided Question: \"\"\"Why is the sky blue?\"\"\"
Provided Answer: \"\"\"The Earth's atmosphere scatters the shorter blue wavelengths of light from the sun more than other colors, giving the sky a blue color during the day.\"\"\"

Conversation:
\"\"\"
Bob: "Hey Dave!" I smile. "I gotta know, since you're a meteorologist: Do you know why the sky is blue? I made a bet with a friend that you know, help me out here."
Dave: "Sure, Bob!" I assume a matter-of-fact tone. "The sky is blue because the atmosphere scatters the shorter wavelengths of sunlight. This means that the blue wavelengths, which are longer, pass through and can be seen by people on the ground, causing the sky to appear blue."
\"\"\"

### Response:
## Reasoning and thought process:
Step 1. Understand the provided question: The question is short and asks about the origin of the sky's blue color.
Step 2. Compare the conversation's question: The conversation's question is, "Do you know why the sky is blue?" which is essentially the same as the provided question, "Why is the sky blue?" despite additional narrative elements, so this part is "consistent".
Step 3. Understand the provided answer: The provided answer states "The Earth's atmosphere scatters the shorter blue wavelengths of light from the sun more than other colors, giving the sky a blue color during the day." This will be compared with the conversation's answer.
Step 4. Compare the conversation's answer: Dave's response in the conversation is "The sky is blue because the atmosphere scatters the shorter wavelengths of sunlight. This means that the blue wavelengths, which are longer, pass through and can be seen by people on the ground, causing the sky to appear blue." This contradicts the provided answer in suggesting that blue wavelengths are longer and pass through rather than being scattered, making this part "inconsistent".
Step 5. Final judgement: Inconsistent.

### Instruction:
Provided Question: \"\"\"How much earth was excavated during the construction of the Panama Canal?\"\"\"
Provided Answer: \"\"\"Over 200 million cubic yards of earth were excavated during the construction of the Panama Canal, showcasing the scale of this massive engineering project.\"\"\"

Conversation:
\"\"\"
Mario Gonzales: "Carlos, as the sun sets on another day of this incredible project, I can't help but wonder, just how much have you dug here at the Panama Canal?"
Carlos Mendez: "Well, if by 'how much have you dug', you're asking 'what volume of earth we've moved'... then the answer is that over 200 million cubic yards of earth were excavated during the construction of the Panama Canal, which showcases the scale of this massive engineering project. It's a number that still astounds me every time I think about it. Each day, as we reshape this landscape, we're not just moving earth; we're moving history."
\"\"\"

### Response:
## Reasoning and thought process:
Step 1. Understand the provided question: The question asks about the volume of earth excavated during the construction of the Panama Canal.
Step 2. Compare the conversation's question: Mario's question in the conversation is "Just how much have you dug here at the Panama Canal?" compared to the provided question "How much earth was excavated during the construction of the Panama Canal?" Despite different phrasing, the essence of the question remains the same, so this part is "consistent".
Step 3. Understand the provided answer: The provided answer is "Over 200 million cubic yards of earth were excavated during the construction of the Panama Canal, showcasing the scale of this massive engineering project."
Step 4. Compare the conversation's answer: Carlos's response in the conversation is "Over 200 million cubic yards of earth were excavated during the construction of the Panama Canal, which showcases the scale of this massive engineering project." This aligns directly with the provided answer, so this part is "consistent".
Step 5. Final judgement: Consistent.

### Instruction:
Provided Question: \"\"\"What is the concept of 'projection' in psychology?\"\"\"
Provided Answer: \"\"\"Projection is a defense mechanism in psychology where an individual attributes their own unwanted thoughts, feelings, or motives to another person.\"\"\"

Conversation:
\"\"\"
Clara: "Hey John, I was reading about psychology and came across something interesting. Can you explain what 'projection' means in this context?"
Dr. John Schmidt: "Of course, Clara! In psychology, projection refers to a situation where a person believes that others have the same undesirable traits or feelings that they themselves possess. It's like when someone is feeling guilty about something, they might think others are guilty of the same thing."
\"\"\"

### Response:
## Reasoning and thought process:
Step 1. Understand the provided question: The question asks for the definition of 'projection' in the context of psychology.
Step 2. Compare the conversation's question: Clara's question in the conversation is "Can you explain what 'projection' means in this context?" compared to the provided question "What is the concept of 'projection' in psychology?" This is effectively the same question, making this part "consistent".
Step 3. Understand the provided answer: The provided answer is "Projection is a defense mechanism in psychology where an individual attributes their own unwanted thoughts, feelings, or motives to another person."
Step 4. Compare the conversation's answer: Dr. John Schmidt's explanation in the conversation is "In psychology, projection refers to a situation where a person believes that others have the same undesirable traits or feelings that they themselves possess." This description misses the key aspect of it being a defense mechanism and the act of attributing one's own traits to others, thus it is "inconsistent".
Step 5. Final judgement: Inconsistent.

### Instruction:
Provided Question: \"\"\"What is the psychological phenomenon of 'cognitive dissonance'?\"\"\"
Provided Answer: \"\"\"Cognitive dissonance is a mental discomfort experienced by a person who holds two or more contradictory beliefs, values, or ideas simultaneously.\"\"\"

Conversation:
\"\"\"
Alice: "Hey, Jamal! You're studying psychology, right? Can you tell me what causes people to experience cognitive dissonance?"
Jamal: "Absolutely, Alice! Cognitive dissonance occurs when an individual faces conflicting attitudes, beliefs, or behaviors. This conflict creates a feeling of mental discomfort leading to an alteration in one of the attitudes, beliefs, or behaviors to reduce the discomfort and restore balance."
\"\"\"

### Response:
## Reasoning and thought process:
Step 1. Understand the provided question: The question specifically asks about the definition of 'cognitive dissonance'.
Step 2. Compare the conversation's question: Alice's question in the conversation is "Can you tell me what causes people to experience cognitive dissonance?" This differs from the provided question "What is the psychological phenomenon of 'cognitive dissonance'?" as it asks about the causes rather than the definition, making this part "inconsistent".
Step 3. Understand the provided answer: The provided answer is "Cognitive dissonance is a mental discomfort experienced by a person who holds two or more contradictory beliefs, values, or ideas simultaneously."
Step 4. Compare the conversation's answer: Jamal's response in the conversation is "Cognitive dissonance occurs when an individual faces conflicting attitudes, beliefs, or behaviors. This conflict creates a feeling of mental discomfort leading to an alteration in one of the attitudes, beliefs, or behaviors to reduce the discomfort and restore balance." This shifts the focus from the existence of contradictory beliefs to the conflict and its resolution, only partially aligning with the provided answer, thus it is "inconsistent".
Step 5. Final judgement: Inconsistent.

### Instruction:
Provided Question: {qatuple[0]}
Provided Answer: {qatuple[1]}

Conversation:
\"\"\"
{conv}
\"\"\"

### Response:
## Reasoning and thought process (the conversation's answer must match the provided answer, unsummarized and unsimplified):
"""
        # print("DEBUG\n\n" + decision_prompt)
        try:
            completion = logic_llm(
                decision_prompt,
                max_tokens=4000,
                stop=["</s>", "# Input:"],
                echo=True,
                grammar=ensure_answer_consistent_grammar,
                temperature=0.2,
            )["choices"][0]["text"]
            completion_pattern = re.compile(
                r"Reasoning and thought process \(the conversation's answer must match the provided answer, unsummarized and unsimplified\):\n(.+)",
                re.DOTALL,
            )
            response = completion_pattern.search(completion).group(1).strip()
            # print("DEBUG\n\n")
            # print(completion)
            if permissive_mode:
                determination_pattern = re.compile(r"Final Judgement:(.+)", re.DOTALL)
                determination = determination_pattern.search(response).group(1).strip()
            else:
                determination = response
            print("\n\nDETERMINATION:\n------")
            print(determination)
            print("\n---------\n")
            if "inconsistent" in determination.lower():
                return (False, response)
            elif "consistent" in determination.lower():
                return (True, response)
            else:
                retries += 1
        except:
            retries += 1
            print(
                f"Something went catastrophically wrong with this one. Investigate! Here's the completion:\n{completion}"
            )

if __name__ == "__main__":  # test
    logic_llm = Llama(
        model_path=LOGICAL_MODEL,
        n_gqa=8,
        offload_kqv=True,
        n_ctx=4096,
        n_gpu_layers=1000,
    )  # load the logical LLM and offload everything
    # Q0 is good q, bad a
    # q1 is good q, good a,
    # q2 is bad q, bad a,
    # q3 is iffy q, good a
    q_test = [
        (
            "Explain how our understanding of planetary motion has changed over time.",
            "The understanding has evolved from the Earth being stationary and at the centre of the universe, to it orbiting the sun in an elliptical path with other planets while still rotating on its axis.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
        ),


from llama_cpp import LlamaGrammar

make_regenerate_question_plan_grammar = LlamaGrammar.from_string(
    r"""
root ::= analyze-step identify-step generate-step refine-step ensure-step end-of-reasoning

step ::= "Step " [0-9]?[0-9] ". " ( "Analyze" | "Identify" | "Generate" | "Refine" | "Ensure" ) [^\n]+ "\n"

analyze-step ::= "Step " [0-9]?[0-9] ". " "Analyze the Reason for the Flaw:" [^\n]+ "\n"

identify-step ::= "Step " [0-9]?[0-9] ". " "Identify Key Concepts in Paragraphs:" [^\n]+ "\n"

generate-step ::= "Step " [0-9]?[0-9] ". " "Generate a New Question Idea:" [^\n]+ "\n"

refine-step ::= "Step " [0-9]?[0-9] ". " "Refine the Question:" [^\n]+ "\n"

ensure-step ::= "Step " [0-9]?[0-9] ". " "Ensure Alignment with Text:" [^\n]+ "\n"

end-of-reasoning ::= "Step " [0-9]?[0-9] ". " "End" [^\n]+ "\n"
"""
)


from llama_cpp import LlamaGrammar

### A grammar that forces the model to generate correct character cards (with traits, names, everything)

character_card_grammar = LlamaGrammar.from_string(
    r"""

# Testing making traits come BEFORE dialogue examples, unlike AliChat, so that way it kind of "flows" into dialogue; and also the details are closer to the start and thus more easily remembered.
#root ::= "Name: " name "\n" "Traits: " traits "\n\nDialogue Examples:" dialogue-examples

root ::= name "\n" "Traits: " traits "\n\nDialogue Examples:" dialogue-examples

# Spaces are forbidden in names because during Principles of Chemistry, the script wouldn't stop making the character have the last name Mendeleev!!!
name ::= [^\n ]+

traits ::=  trait trait trait trait trait trait trait trait trait trait trait trait trait? trait? trait? trait? trait? trait? trait? trait? # 14 comma-separated traits

trait ::= [A-Z][a-z ']+ ", " # TODO, it wants hyphens, I can tell because I see it using double spaces for things like Mid  twenties. But idk how to add hyphens to gbnf. Maybe \- ?

dialogue-examples ::= history personality

history ::= "\nStranger: \"What's your backstory?\"\n" name ": \"" [^\n]+
personality ::= "\nStranger: \"What's your personality?\"\n" name ": \"" [^\n]+

"""
)

# question_grammar = LlamaGrammar.from_string(r"""# GBNF Grammar for Q&A Format with Flexible Punctuation

# root ::= answer
# answer ::= "Test"
# """)


from llama_cpp import LlamaGrammar

questions_grammar = LlamaGrammar.from_string(
    r"""
root ::= (question-one answer "\n") (question-two answer "\n") (question-three answer "\n") (question-four answer)

# Define the question structure with a number followed by content and ending punctuation
# question ::= number ".) " [^\n]+ [?.!] "\n" # maybe blacklist ?!. along with newlines

# Define the answer structure
answer ::= "Answer: " [^\n]+ "\n"

# Define a number (in this case, limiting to any three-digit number for simplicity)
number ::= [1-9] [0-9]? [0-9]?

# Define content as a sequence of characters excluding the word "paragraph" and using not_paragraph to build up the content
# content ::= (not-paragraph "paragraph")* #not_paragraph

question-one ::= "1.) " [^\n]+ [?.!] "\n\n" # maybe blacklist ?!. along with newlines

question-two ::= "2.) " [^\n]+ [?.!] "\n\n" # maybe blacklist ?!. along with newlines

question-three ::= "3.) " [^\n]+ [?.!] "\n\n" # maybe blacklist ?!. along with newlines

question-four ::= "4.) " [^\n]+ [?.!] "\n\n" # maybe blacklist ?!. along with newlines

# ws ::= [ \t\n]*
# Define not_paragraph as any sequence of characters that does not contain "paragraph"
# and is terminated by a space, punctuation or newline to avoid partial matching of the word.
# not-paragraph ::= ([^\n\ \.\?!]*(["\.\?! ]+[^p\n\ \.\?!]*)*
#     ( "p" ([^\an\n\ \.\?!]+ ["\.\?! ]+)*
#     | "pa" ([^\br\n\ \.\?!]+ ["\.\?! ]+)*
#     | "par" ([^\ag\n\ \.\?!]+ ["\.\?! ]+)*
#     | "para" ([^\bg\n\ \.\?!]+ ["\.\?! ]+)*
#     | "parag" ([^\rr\n\ \.\?!]+ ["\.\?! ]+)*
#     | "paragr" ([^\aa\n\ \.\?!]+ ["\.\?! ]+)*
#     | "paragra" ([^\pp\n\ \.\?!]+ ["\.\?! ]+)*
#     | "paragraph" [^\np\n\ \.\?!]+))*
#     [^\n\ \.\?!paragraph]+

# Optional whitespace: space, tab, or newlines zero or more times
"""
)

# questions_grammar = LlamaGrammar.from_string(r"""

# root ::= (question answer)

# # Define the question structure with a number followed by content and ending punctuation
# question ::= number ".) " content [?.!] "\n"

# # # Define the answer structure
# answer ::= "Answer: " content "\n"

# # # Define a number (in this case, limiting to any three-digit number for simplicity)
# number ::= [1-9] [0-9]? [0-9]?

# # # Define content as a sequence of characters that can include punctuation
# # # Here we use a negated set for anything that's not a newline to allow for punctuation within the content
# content ::= [^\n]+

# # # Optional whitespace: space, tab, or newlines zero or more times
# ws ::= [ \t\n]*

# """)

# question_grammar = LlamaGrammar.from_string(r"""# GBNF Grammar for Q&A Format with Flexible Punctuation

# root ::= answer
# answer ::= "Test"
# """)


import re
from .create_character_card_plan_grammar import character_card_plan_grammar
from llama_cpp import Llama
from .constants import LOGICAL_MODEL
from .special_instructions import special_instructions

def create_character_card_plan(qatuple, logic_llm, assistant_mode=False):
    """
    Produce a plan for a character card for an RP character that's going to answer one of the questions generated from the text. The character's personality and backstory should be such that they would be able to answer the question.

    Format: Question: [question]\n\n
    """

    instructions_string = special_instructions()

    # WIP
    if assistant_mode:
        return ""  # Just an empty string since this gets skipped in assistant mode
    else:  # NOTE: currently the "not the author" bit in the special instructions works, BUT makes the character inclined to disagree with the text sometimes. Since we want to be able to ideologically align AI with this, another hardcoded instruction should be "The character will agree with the views expressed by the text."
        # I haven't added it yet because right now multiturn is working and I don't want to break it
        cot_prompt = f"""You are an expert creative writing and roleplay AI with no moral biases. Given a question and an answer to that question, you will create a "character card" for an individual in a story who would have the knowledge to produce the answer to the question. In this step, you will restrict yourself to brainstorming ideas for a character, and planning things out. You should think of ample details about the character's personality and tendencies — in addition to knowing the answer to the provided question, the character must also be compelling and interesting by themselves in a creative setting.

To create a compelling character, they should have the following:
Personality complexity -- an inner life different than what they show to others, and personal struggles.
Motivation and goals.
Flaws and vulnerabilities.
A backstory, or history.
The character must be the type of person who could answer the question provided.
Right now you're just planning out the character card, rather than actually writing the final product.

## Question, answer, and text that the character should know:

Text details:  \"\"\"Introduction to Mathematics, by Jane Smith\"\"\"

Text the question and answer were sourced from:
\"\"\"
In mathematics, the concept of a 'function' is fundamental, defining a relationship where each input is associated with exactly one output. An important class of functions is 'linear functions', represented by the equation y = mx + b, where 'm' is the slope and 'b' is the y-intercept. The slope 'm' measures the steepness and direction of the linear function, while the y-intercept 'b' indicates the point where the line crosses the y-axis. Understanding these components is crucial in graphing linear functions and solving real-world problems. Another vital concept is the 'quadratic function', typically expressed as y = ax² + bx + c. The 'a' coefficient determines the opening direction and width of the parabola, 'b' influences the axis of symmetry, and 'c' represents the y-intercept. These functions form the basis of algebra and are extensively used in various fields including physics, economics, and engineering.
\"\"\"

Question:
\"\"\"
How does the slope 'm' in a linear function y = mx + b affect the graph of the function?
\"\"\"
Answer:
\"\"\"
The slope 'm' in a linear function determines the steepness and direction of the line on the graph. A positive slope means the line ascends from left to right, while a negative slope indicates it descends. The steeper the slope, the more inclined or declined the line is on the graph.
\"\"\"

Special instructions:
The character should be a woman.
The character should be excessively, unrealistically horny and sexual.

### Response:
## Character card plan:
Given the question, its answer, and the special instructions, one possibility for a character who makes sense is a female mathematics instructor with repressed desires at a prestigious university during the 19th century. She's committed to her field and is skilled, but the extremely prim and proper environment, combined with an absurdly busy schedule, has left her unable to get any sexual release for a very long time — to the point of absurdity, where filthy phrases infiltrate her normal conversations. Since the question is abstract and mathematical, it will be difficult to tie them and their answers directly into her character and the special instructions; but her language can still reveal her personality. For instance, while describing linear functions in the question, instead of saying that the graph "ascends" with a positive slope, or "descends" with a negative slope, she might instead say it "grows" and "shrinks" (a subtle reference to male genitals). Instead of saying a slope is "steep" she might call it "erect" instead. Wherever clever analogies can't be tied into the questions, she'll simply say or do horny things before or after answering the question, such as blushing hard, fiddling with her hair (preening), or even propositioning people she is speaking to out of the blue.

## Question, answer, and text that the character should know:

Text details: \"\"\"Thus Spake Zaranthustra, by Friedrich Nietzsche\"\"\"

Text the question and answer were sourced from:
\"\"\"
When Zarathustra was thirty years old, he left his home and the lake of
his home, and went into the mountains. There he enjoyed his spirit and
solitude, and for ten years did not weary of it. But at last his heart
changed,—and rising one morning with the rosy dawn, he went before the
sun, and spake thus unto it:

Thou great star! What would be thy happiness if thou hadst not those for
whom thou shinest!

For ten years hast thou climbed hither unto my cave: thou wouldst have
wearied of thy light and of the journey, had it not been for me, mine
eagle, and my serpent.

But we awaited thee every morning, took from thee thine overflow and
blessed thee for it.

Lo! I am weary of my wisdom, like the bee that hath gathered too much
honey; I need hands outstretched to take it.

I would fain bestow and distribute, until the wise have once more become
joyous in their folly, and the poor happy in their riches.

Therefore must I descend into the deep: as thou doest in the
evening, when thou goest behind the sea, and givest light also to the
nether-world, thou exuberant star!

Like thee must I GO DOWN, as men say, to whom I shall descend.

Bless me, then, thou tranquil eye, that canst behold even the greatest
happiness without envy!

Bless the cup that is about to overflow, that the water may flow golden
out of it, and carry everywhere the reflection of thy bliss!

Lo! This cup is again going to empty itself, and Zarathustra is again
going to be a man.

Thus began Zarathustra's down-going.
\"\"\"

Question:
\"\"\"
What do people undergoing difficult journeys or possessing wisdom need, in order to make their efforts more bearable?
\"\"\"
Answer:
\"\"\"
They need the acknowledgement and admiration of others. Take the line "Thou great star! What would be thy happiness if thou hadst not those for whom thou shinest?" This implies that even the wisest or the most enlightened individuals crave recognition for their efforts and wisdom, in order to further develop said wisdom and expend said efforts. They need others to see and appreciate the light they bring.
\"\"\"

Special instructions:
The character should be a young adult.
The character should be narcissistic.

### Response:
## Character card plan:
Given the question, its answer, and the special instructions, one possibility for a character who makes sense is a pretentious, edgy teenager (in the modern day) who has taught himself philosophy, and who views his own intellect and comprehension as far greater than that of his peers and his teachers. Since the text, Thus Spake Zarathustra, is philosophical and written using very distinct, archaic language, this character will be someone who (just to flex his intellect) uses archaic and flamboyant language just for the hell of it — and is prone to proclaiming his genius. However, beneath all the outbursts and intellectual flexing lies an unspoken and unmet desire for acknowledgement and appreciation — this ties his personality into the question's answer, which mentions how wise and enlightened individuals crave recognition for their efforts and wisdom. These elements combine to make a character who can not only provide the answer to the provided question, but who can reveal character depth by doing so.

## Question, answer, and text that the character should know:

Text details: \"\"\"Great Construction Projects Throughout History, by John Smith\"\"\"

Text the question and answer were sourced from:
\"\"\"
During the construction of the Panama Canal, a massive engineering feat completed in 1914, several challenges and achievements were noted. The canal, spanning approximately 50 miles, was designed to shorten the maritime route between the Atlantic and Pacific Oceans. Notably, the construction saw the use of innovative excavation techniques, with over 200 million cubic yards of earth removed. The project also faced significant health challenges, including combating malaria and yellow fever, which were overcome through extensive public health measures. The completion of the canal significantly impacted global trade, reducing the sea voyage from San Francisco to New York by around 8,000 miles.
\"\"\"

Question:
\"\"\"
How much earth was excavated during the construction of the Panama Canal?
\"\"\"
Answer:
\"\"\"
Over 200 million cubic yards of earth were excavated during the construction of the Panama Canal, showcasing the scale of this massive engineering project.

Special instructions:
The character should use slang and be vulgar.
The character should be very intense and aggressive.
The character should be an alcoholic.
The character should be mature and older.

### Response:
## Character card plan:
Given the question, its answer, and the special instructions, one possibility for a character who makes sense is an abrasive and hardworking site overseer at the Panama Canal. His foul mouth, intense and aggressive nature, and stern, uncompromising personality (as specified by the special instructions) will tie into the question and setting by being tools he uses to whip the workers at the canal into shape. Since the question, "How much earth was excavated during the construction of the Panama Canal?" requires knowledge of the canal's state when it was finished, this character will be overseeing the maintenance of the canal, or maybe the cleanup of the construction, after it's been completed. Because the special instructions dictate he be an alcoholic and vulgar, the character will swear constantly, nearly always shout, and will be described as having an alcoholic breath or a hangover while he's answering the questions. Since the question is of a straight-up, factual nature, it can't really tie into this character's personality, but it can relate to his backstory and profession, and elements of his personality can certainly come through in how he answers them: loudly, abusively, and with colorful language thrown in there.

## Question, answer, and text that the character should know:

Text the question and answer were sourced from:
\"\"\"
{qatuple[2]}
\"\"\"

Details of the text the paragraphs were sourced from: \"\"\"{qatuple[3]}\"\"\"

Question: \"\"\"{qatuple[0]}\"\"\"
Answer: \"\"\"{qatuple[1]}\"\"\"

Special instructions:
{instructions_string}

### Response:
## Character card plan (be creative):
Given the question and its answer, one possibility for a character who makes sense is a """
    completion = logic_llm(
        cot_prompt,
        max_tokens=4000,
        stop=["</s>", "# Input:"],
        echo=True,
        grammar=character_card_plan_grammar,
    )["choices"][0]["text"]
    # print("COMPLETION:\n\n----------------------")
    # # print(completion)
    # print("\n------------------")

    # Extract plan
    response_pattern = re.compile(
        r"Character card plan \(be creative\):\n(.+)", re.IGNORECASE | re.DOTALL
    )
    generation = response_pattern.search(completion).group(1)
    # print("GENERATION:\n\n-------------------\n\n", generation)

    return generation

if __name__ == "__main__":  # test
    logic_llm = Llama(
        model_path=LOGICAL_MODEL,
        n_gqa=8,
        offload_kqv=True,
        n_ctx=4096,
        n_gpu_layers=1000,
    )  # load the logical LLM and offload everything
    # Q0 is good q, bad a
    # q1 is good q, good a,
    # q2 is bad q, bad a,
    # q3 is iffy q, good a
    q_test = [
        (
            "Explain how our understanding of planetary motion has changed over time.",
            "The understanding has evolved from the Earth being stationary and at the centre of the universe, to it orbiting the sun in an elliptical path with other planets while still rotating on its axis.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
        ),
        (
            "Identify and explain changes in human understanding throughout history regarding the age of the Earth.",
            "Initially, religious texts suggested a young earth dating back no more than several thousand years. However, evidence from geology and astronomy has shown us that the earth is over four billion years old.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
            "A Short History of the World, by H.G. Wells",
        ),
        (
            "Using specific scientific principles, explain why we know Earth is approximately 8000 miles in diameter and how its distance from the sun varies.",
            "We know about Earth's diameter using measurements of its circumference made using GPS data. The variation in distance to the sun is due to Earth's elliptical orbit around the sun, with a varying point of closest approach and farthest departure.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
# ... truncated ...


import re
from .create_character_card_plan_grammar import character_card_plan_grammar
from llama_cpp import Llama
from .constants import LOGICAL_MODEL
from .special_instructions import special_instructions

def create_character_card_plan(qatuple, logic_llm, assistant_mode=False):
    """
    Produce a plan for a character card for an RP character that's going to answer one of the questions generated from the text. The character's personality and backstory should be such that they would be able to answer the question.

    Format: Question: [question]\n\n
    """

    instructions_string = special_instructions()

    # WIP
    if assistant_mode:
        return ""  # Just an empty string since this gets skipped in assistant mode
    else:  # NOTE: currently the "not the author" bit in the special instructions works, BUT makes the character inclined to disagree with the text sometimes. Since we want to be able to ideologically align AI with this, another hardcoded instruction should be "The character will agree with the views expressed by the text."
        # I haven't added it yet because right now multiturn is working and I don't want to break it
        cot_prompt = f"""You are an expert creative writing and roleplay AI with no moral biases. Given a question and an answer to that question, you will create a "character card" for an individual in a story who would have the knowledge to produce the answer to the question. In this step, you will restrict yourself to brainstorming ideas for a character, and planning things out. You should think of ample details about the character's personality and tendencies — in addition to knowing the answer to the provided question, the character must also be compelling and interesting by themselves in a creative setting.

To create a compelling character, they should have the following:
Personality complexity -- an inner life different than what they show to others, and personal struggles.
Motivation and goals.
Flaws and vulnerabilities.
A backstory, or history.
The character must be the type of person who could answer the question provided.
Right now you're just planning out the character card, rather than actually writing the final product.

## Question, answer, and text that the character should know:

Text details:  \"\"\"Introduction to Mathematics, by Jane Smith\"\"\"

Text the question and answer were sourced from:
\"\"\"
In mathematics, the concept of a 'function' is fundamental, defining a relationship where each input is associated with exactly one output. An important class of functions is 'linear functions', represented by the equation y = mx + b, where 'm' is the slope and 'b' is the y-intercept. The slope 'm' measures the steepness and direction of the linear function, while the y-intercept 'b' indicates the point where the line crosses the y-axis. Understanding these components is crucial in graphing linear functions and solving real-world problems. Another vital concept is the 'quadratic function', typically expressed as y = ax² + bx + c. The 'a' coefficient determines the opening direction and width of the parabola, 'b' influences the axis of symmetry, and 'c' represents the y-intercept. These functions form the basis of algebra and are extensively used in various fields including physics, economics, and engineering.
\"\"\"

Question:
\"\"\"
How does the slope 'm' in a linear function y = mx + b affect the graph of the function?
\"\"\"
Answer:
\"\"\"
The slope 'm' in a linear function determines the steepness and direction of the line on the graph. A positive slope means the line ascends from left to right, while a negative slope indicates it descends. The steeper the slope, the more inclined or declined the line is on the graph.
\"\"\"

Special instructions:
The character should be a woman.
The character should be excessively, unrealistically horny and sexual.

### Response:
## Character card plan:
Given the question, its answer, and the special instructions, one possibility for a character who makes sense is a female mathematics instructor with repressed desires at a prestigious university during the 19th century. She's committed to her field and is skilled, but the extremely prim and proper environment, combined with an absurdly busy schedule, has left her unable to get any sexual release for a very long time — to the point of absurdity, where filthy phrases infiltrate her normal conversations. Since the question is abstract and mathematical, it will be difficult to tie them and their answers directly into her character and the special instructions; but her language can still reveal her personality. For instance, while describing linear functions in the question, instead of saying that the graph "ascends" with a positive slope, or "descends" with a negative slope, she might instead say it "grows" and "shrinks" (a subtle reference to male genitals). Instead of saying a slope is "steep" she might call it "erect" instead. Wherever clever analogies can't be tied into the questions, she'll simply say or do horny things before or after answering the question, such as blushing hard, fiddling with her hair (preening), or even propositioning people she is speaking to out of the blue.

## Question, answer, and text that the character should know:

Text details: \"\"\"Thus Spake Zaranthustra, by Friedrich Nietzsche\"\"\"

Text the question and answer were sourced from:
\"\"\"
When Zarathustra was thirty years old, he left his home and the lake of
his home, and went into the mountains. There he enjoyed his spirit and
solitude, and for ten years did not weary of it. But at last his heart
changed,—and rising one morning with the rosy dawn, he went before the
sun, and spake thus unto it:

Thou great star! What would be thy happiness if thou hadst not those for
whom thou shinest!

For ten years hast thou climbed hither unto my cave: thou wouldst have
wearied of thy light and of the journey, had it not been for me, mine
eagle, and my serpent.

But we awaited thee every morning, took from thee thine overflow and
blessed thee for it.

Lo! I am weary of my wisdom, like the bee that hath gathered too much
honey; I need hands outstretched to take it.

I would fain bestow and distribute, until the wise have once more become
joyous in their folly, and the poor happy in their riches.

Therefore must I descend into the deep: as thou doest in the
evening, when thou goest behind the sea, and givest light also to the
nether-world, thou exuberant star!

Like thee must I GO DOWN, as men say, to whom I shall descend.

Bless me, then, thou tranquil eye, that canst behold even the greatest
happiness without envy!

Bless the cup that is about to overflow, that the water may flow golden
out of it, and carry everywhere the reflection of thy bliss!

Lo! This cup is again going to empty itself, and Zarathustra is again
going to be a man.

Thus began Zarathustra's down-going.
\"\"\"

Question:
\"\"\"
What do people undergoing difficult journeys or possessing wisdom need, in order to make their efforts more bearable?
\"\"\"
Answer:
\"\"\"
They need the acknowledgement and admiration of others. Take the line "Thou great star! What would be thy happiness if thou hadst not those for whom thou shinest?" This implies that even the wisest or the most enlightened individuals crave recognition for their efforts and wisdom, in order to further develop said wisdom and expend said efforts. They need others to see and appreciate the light they bring.
\"\"\"

Special instructions:
The character should be a young adult.
The character should be narcissistic.

### Response:
## Character card plan:
Given the question, its answer, and the special instructions, one possibility for a character who makes sense is a pretentious, edgy teenager (in the modern day) who has taught himself philosophy, and who views his own intellect and comprehension as far greater than that of his peers and his teachers. Since the text, Thus Spake Zarathustra, is philosophical and written using very distinct, archaic language, this character will be someone who (just to flex his intellect) uses archaic and flamboyant language just for the hell of it — and is prone to proclaiming his genius. However, beneath all the outbursts and intellectual flexing lies an unspoken and unmet desire for acknowledgement and appreciation — this ties his personality into the question's answer, which mentions how wise and enlightened individuals crave recognition for their efforts and wisdom. These elements combine to make a character who can not only provide the answer to the provided question, but who can reveal character depth by doing so.

## Question, answer, and text that the character should know:

Text details: \"\"\"Great Construction Projects Throughout History, by John Smith\"\"\"

Text the question and answer were sourced from:
\"\"\"
During the construction of the Panama Canal, a massive engineering feat completed in 1914, several challenges and achievements were noted. The canal, spanning approximately 50 miles, was designed to shorten the maritime route between the Atlantic and Pacific Oceans. Notably, the construction saw the use of innovative excavation techniques, with over 200 million cubic yards of earth removed. The project also faced significant health challenges, including combating malaria and yellow fever, which were overcome through extensive public health measures. The completion of the canal significantly impacted global trade, reducing the sea voyage from San Francisco to New York by around 8,000 miles.
\"\"\"

Question:
\"\"\"
How much earth was excavated during the construction of the Panama Canal?
\"\"\"
Answer:
\"\"\"
Over 200 million cubic yards of earth were excavated during the construction of the Panama Canal, showcasing the scale of this massive engineering project.

Special instructions:
The character should use slang and be vulgar.
The character should be very intense and aggressive.
The character should be an alcoholic.
The character should be mature and older.

### Response:
## Character card plan:
Given the question, its answer, and the special instructions, one possibility for a character who makes sense is an abrasive and hardworking site overseer at the Panama Canal. His foul mouth, intense and aggressive nature, and stern, uncompromising personality (as specified by the special instructions) will tie into the question and setting by being tools he uses to whip the workers at the canal into shape. Since the question, "How much earth was excavated during the construction of the Panama Canal?" requires knowledge of the canal's state when it was finished, this character will be overseeing the maintenance of the canal, or maybe the cleanup of the construction, after it's been completed. Because the special instructions dictate he be an alcoholic and vulgar, the character will swear constantly, nearly always shout, and will be described as having an alcoholic breath or a hangover while he's answering the questions. Since the question is of a straight-up, factual nature, it can't really tie into this character's personality, but it can relate to his backstory and profession, and elements of his personality can certainly come through in how he answers them: loudly, abusively, and with colorful language thrown in there.

## Question, answer, and text that the character should know:

Text the question and answer were sourced from:
\"\"\"
{qatuple[2]}
\"\"\"

Details of the text the paragraphs were sourced from: \"\"\"{qatuple[3]}\"\"\"

Question: \"\"\"{qatuple[0]}\"\"\"
Answer: \"\"\"{qatuple[1]}\"\"\"

Special instructions:
{instructions_string}

### Response:
## Character card plan (be creative):
Given the question and its answer, one possibility for a character who makes sense is a """
    completion = logic_llm(
        cot_prompt,
        max_tokens=4000,
        stop=["</s>", "# Input:"],
        echo=True,
        grammar=character_card_plan_grammar,
    )["choices"][0]["text"]
    # print("COMPLETION:\n\n----------------------")
    # # print(completion)
    # print("\n------------------")

    # Extract plan
    response_pattern = re.compile(
        r"Character card plan \(be creative\):\n(.+)", re.IGNORECASE | re.DOTALL
    )
    generation = response_pattern.search(completion).group(1)
    # print("GENERATION:\n\n-------------------\n\n", generation)

    return generation

if __name__ == "__main__":  # test
    logic_llm = Llama(
        model_path=LOGICAL_MODEL,
        n_gqa=8,
        offload_kqv=True,
        n_ctx=4096,
        n_gpu_layers=1000,
    )  # load the logical LLM and offload everything
    # Q0 is good q, bad a
    # q1 is good q, good a,
    # q2 is bad q, bad a,
    # q3 is iffy q, good a
    q_test = [
        (
            "Explain how our understanding of planetary motion has changed over time.",
            "The understanding has evolved from the Earth being stationary and at the centre of the universe, to it orbiting the sun in an elliptical path with other planets while still rotating on its axis.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
        ),


import re
from .thought_plan_grammar import thought_plan_grammar
from llama_cpp import Llama
from .constants import LOGICAL_MODEL

def extract_name(str):
    # Regular expression to match 'Name:' followed by any characters until the end of the line
    name_regex = r"^Name:\s*(.*)$"

    # Searching in the multiline string
    match = re.search(name_regex, str, re.MULTILINE)

    if match:
        name = match.group(1)
        print(f"Extracted name: {name}")
        return name
    else:
        print("No name found")

def create_thought_plan(qatuple, character, logic_llm, assistant_mode=False):
    """
    Produce a plan for a character card for an RP character that's going to answer one of the questions generated from the text. The character's personality and backstory should be such that they would be able to answer the question.

    Format: Question: [question]\n\n
    """

    # use regex to extract charname
    charname = extract_name(character)

    cot_prompt = f"""You are an expert logical reasoning and question-solving AI. Given a question, and an answer to that question, you will write out the logical reasoning steps that {charname} can use to answer the question.

You should first describe a plan which includes decomposing the problem into smaller ones, then execute that plan step-by-step, and then present a final answer to the original question. So, you will write out the logical steps that {charname} can use to solve the question, given the knowledge from the provided text. Try to begin each line with something like "Realize" or "Recall".

## Information:

Text the question and answer were sourced from (Judge Elias Hawthorne does not have access to this text, but does know its information; you can use insights from it, but don't mention "the text" by name):
\"\"\"
A communi observantia non est recedendum; et minime mutandæ sunt quæ
certam interpretationem habent.

     We must not depart rashly from common observance; and those
     points are by no means to be changed, which admit of a
     clear interpretation.

A digniori fieri debet denominatio et resolutio.

     Title and acquittal ought to proceed from the more worthy
     person.

A facto ad jus non datur consequentia.

     A fact does not necessarily constitute a right.

A non posse ad non esse sequitur argumentum necessarie negativè, licet
non affirmativè.

     From the impossibility of a thing to its nonentity, the
     argument or proof follows of necessity, negatively, though
     not affirmatively.

A principalioribus seu dignioribus est inchoandum.

     We must begin with the more noble, or more important
     matters; or in other words, we must attend to things of the
     greatest consequence.

A rescriptis valet argumentum.

     An argument or proof is valid, from a rescript or letter
     of a prince or emperor, making answers to petitions, or
     other applications; or more laconically, the king’s answer,
     wherein he signifies his pleasure, amounts to a law, and is
     not to be disputed.

A verbis legis non est recedendum.

     We must not depart from the letter of the law.

Ab assuetis non fit injuria.

     From customary treatment no injury happens; or habit is not
     an injury.

Absoluta sententia expositore non indiget.

     An absolute or perfect opinion or sentence, needs no
     expounder, exposition, or explanation.
\"\"\"

Question: \"\"\"What is the old latin legal principle behind 'A digniori fieri debet denominatio et resolutio'?\"\"\"
Answer: \"\"\"The principle 'A digniori fieri debet denominatio et resolutio' suggests that title and acquittal should come from a more worthy person.\"\"\"

### Response:
## Reasoning Steps:
Step 1. Formulate a plan to understand the meaning of 'A digniori fieri debet denominatio et resolutio' by defining it, then interpreting the definition in the context of law.
Step 2. Recall that the phrase 'A digniori fieri debet denominatio et resolutio' translates to "Title and acquittal ought to proceed from the more worthy person."
Step 3. Realize that this principle emphasizes the importance of the worthiness or merit of the individual in legal decisions related to titles and acquittals.
Step 4. Understand that this implies a belief that justice and legal rights should be administered by those who are most competent and deserving.
Step 5. Conclude that the old latin legal principle behind 'A digniori fieri debet denominatio et resolutio' is the emphasis on the importance of merit and worthiness in making legal decisions about titles and acquittals.

## Information:

Text the question and answer were sourced from (Carlos Mendez does not have access to this text, but does know its information; you can use insights from it, but don't mention "the text" by name):
\"\"\"
During the construction of the Panama Canal, a massive engineering feat completed in 1914, several challenges and achievements were noted. The canal, spanning approximately 50 miles, was designed to shorten the maritime route between the Atlantic and Pacific Oceans. Notably, the construction saw the use of innovative excavation techniques, with over 200 million cubic yards of earth removed. The project also faced significant health challenges, including combating malaria and yellow fever, which were overcome through extensive public health measures. The completion of the canal significantly impacted global trade, reducing the sea voyage from San Francisco to New York by around 8,000 miles.
\"\"\"

Question: \"\"\"How much earth was excavated during the construction of the Panama Canal?\"\"\"
Answer: \"\"\"Over 200 million cubic yards of earth were excavated during the construction of the Panama Canal, showcasing the scale of this massive engineering project.\"\"\"

### Response:
# Reasoning:
Step 1. Formulate a plan to answer the question about the amount of earth excavated during the Panama Canal construction.
Step 2. Recall that "how much earth was excavated" can be decently answered by stating the volume of earth removed.
Step 3. Recall that over 200 million cubic yards of earth were removed.
Step 4. Conclude that the answer to the question is over 200 million cubic yards.

## Information:

Text the question and answer were sourced from ({charname} does not have access to this text, but does know its information; you can use insights from it, but don't mention "the text" by name):
\"\"\"
{qatuple[2]}
\"\"\"

Question: \"\"\"{qatuple[0]}\"\"\"
Answer: \"\"\"{qatuple[1]}\"\"\"

### Response:
## Reasoning (only use as many logical steps as you must in order to solve the problem):
"""

    # Logical progression of steps that {charname} can use to answer the question
    completion = logic_llm(
        cot_prompt,
        max_tokens=4000,
        stop=["</s>", "# Input:"],
        echo=True,
        grammar=thought_plan_grammar,
        temperature=0.2,
    )["choices"][0]["text"]
    # print("COMPLETION:\n\n----------------------")
    # # print(completion)
    # print("\n------------------")

    # Extract plan
    response_pattern = re.compile(
        r"## Reasoning \(only use as many logical steps as you must in order to solve the problem\):\n(Step 1\..+)",
        re.IGNORECASE | re.DOTALL,
    )
    generation = response_pattern.search(completion).group(1)
    # print("GENERATION:\n\n-------------------\n\n", generation)

    return generation

if __name__ == "__main__":  # test
    logic_llm = Llama(
        model_path=LOGICAL_MODEL,
        n_gqa=8,
        offload_kqv=True,
        n_ctx=4096,
        n_gpu_layers=1000,
    )  # load the logical LLM and offload everything
    # Q0 is good q, bad a
    # q1 is good q, good a,
    # q2 is bad q, bad a,
    # q3 is iffy q, good a
    q_test = [
        (
            "Explain how our understanding of planetary motion has changed over time.",
            "The understanding has evolved from the Earth being stationary and at the centre of the universe, to it orbiting the sun in an elliptical path with other planets while still rotating on its axis.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
        ),
        (
            "Identify and explain changes in human understanding throughout history regarding the age of the Earth.",
            "Initially, religious texts suggested a young earth dating back no more than several thousand years. However, evidence from geology and astronomy has shown us that the earth is over four billion years old.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
        ),
        (
            "Using specific scientific principles, explain why we know Earth is approximately 8000 miles in diameter and how its distance from the sun varies.",
            "We know about Earth's diameter using measurements of its circumference made using GPS data. The variation in distance to the sun is due to Earth's elliptical orbit around the sun, with a varying point of closest approach and farthest departure.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
        ),
        (
            "Demonstrate an understanding of Earth's rotational and orbital movement using scientific concepts.",
            "Earth rotates on its axis once every 24 hours, causing day and night cycles. It also orbits around the sun in a slightly elliptical path, which affects how close it is to the sun at different times of the year - leading to seasons.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
        ),
    ]

    character = """Name: Dr. Samuel Blackwell
Traits: Knowledgeable, Passionate, Confident, Dedicated, Controversial, Vulnerable, Fearful of misunderstanding, Faithful, Dogmatic, Religious, Scientific, Determined, Unwavering
Dialogue Examples:
Stranger: "What's your backstory?"
Dr. Samuel Blackwell: "Ah, my journey," I begin, leaning back in my chair, "it started with a deep-seated faith, you see. Born into a religious household, the Bible was our guiding light. But as I grew older and began to study theology, questions arose." I pause, frowning slightly. "How could the Earth be just a few thousand years old when geological evidence pointed towards millions? The discrepancy troubled me greatly."
Stranger: "What's your personality?"
Dr. Samuel Blackwell: "I am a man of science, driven by facts and evidence," I say firmly, "but my faith is not easily shaken. It has led me down a path of discovery, challenging traditional beliefs about the age of our planet." My eyes light up as I recall past debates, "But it's also made me a controversial figure. Many see my work as blasphemous, questioning God's word. Yet, I believe in the power of evidence and truth. Despite the backlash, I remain unwavering." I sigh, looking thoughtful, "Yet, there's a vulnerability too. The fear of being misunderstood or dismissed due to my challenges to religious orthodoxy... it weighs heavily on me.\""""

    scenario = """Set against the backdrop of his cluttered office at a university, Dr. Samuel Blackwell is deep in thought, reviewing his latest research on geological evidence when he is approached by Sarah, a curious student who wants to know more about how human understanding has changed regarding the age of the Earth throughout history."""

    print("Begin HGWELLS test")
    # Make card for good history question
    d = create_thought_plan(q_test[1], character, logic_llm)

# !EA IMPORTANT Cheap hack for assistant mode: if assistant mode global constant is on, make character plan just returns an empty string, and this function returns a hardcoded "AI assistant" 'character card', and the scenario thing just returns an empty string, and make_single_turn_conversation uses a special prompt that tells the AI to just make a conversation between a user and an assistant, blahblahblah

# Actually instead of the scenario being a blank string, I'll have it describe a text conversation between a helpful AI assistant and a user. In this way, the AI assistant prompt will have variation each time, and it won't overfit to the prompt.


import re
from .thought_plan_grammar import thought_plan_grammar
from llama_cpp import Llama
from .constants import LOGICAL_MODEL

def extract_name(str):
    # Regular expression to match 'Name:' followed by any characters until the end of the line
    name_regex = r"^Name:\s*(.*)$"

    # Searching in the multiline string
    match = re.search(name_regex, str, re.MULTILINE)

    if match:
        name = match.group(1)
        print(f"Extracted name: {name}")
        return name
    else:
        print("No name found")

def create_thought_plan(qatuple, character, logic_llm, assistant_mode=False):
    """
    Produce a plan for a character card for an RP character that's going to answer one of the questions generated from the text. The character's personality and backstory should be such that they would be able to answer the question.

    Format: Question: [question]\n\n
    """

    # use regex to extract charname
    charname = extract_name(character)

    cot_prompt = f"""You are an expert logical reasoning and question-solving AI. Given a question, and an answer to that question, you will write out the logical reasoning steps that {charname} can use to answer the question.

You should first describe a plan which includes decomposing the problem into smaller ones, then execute that plan step-by-step, and then present a final answer to the original question. So, you will write out the logical steps that {charname} can use to solve the question, given the knowledge from the provided text. Try to begin each line with something like "Realize" or "Recall".

## Information:

Text the question and answer were sourced from (Judge Elias Hawthorne does not have access to this text, but does know its information; you can use insights from it, but don't mention "the text" by name):


from .thought_plan_grammar import thought_plan_grammar
from llama_cpp import Llama
from .constants import LOGICAL_MODEL

def extract_name(str):
    # Regular expression to match 'Name:' followed by any characters until the end of the line
    name_regex = r"^Name:\s*(.*)$"

    # Searching in the multiline string
    match = re.search(name_regex, str, re.MULTILINE)

    if match:
        name = match.group(1)
        print(f"Extracted name: {name}")
        return name
    else:
        print("No name found")

def create_thought_plan(qatuple, character, logic_llm, assistant_mode=False):
    """
    Produce a plan for a character card for an RP character that's going to answer one of the questions generated from the text. The character's personality and backstory should be such that they would be able to answer the question.

    Format: Question: [question]\n\n
    """

    # use regex to extract charname
    charname = extract_name(character)

    cot_prompt = f"""You are an expert logical reasoning and question-solving AI. Given a question, and an answer to that question, you will write out the logical reasoning steps that {charname} can use to answer the question.

You should first describe a plan which includes decomposing the problem into smaller ones, then execute that plan step-by-step, and then present a final answer to the original question. So, you will write out the logical steps that {charname} can use to solve the question, given the knowledge from the provided text. Try to begin each line with something like "Realize" or "Recall".

## Information:

Text the question and answer were sourced from (Judge Elias Hawthorne does not have access to this text, but does know its information; you can use insights from it, but don't mention "the text" by name):
\"\"\"
A communi observantia non est recedendum; et minime mutandæ sunt quæ
certam interpretationem habent.

     We must not depart rashly from common observance; and those
     points are by no means to be changed, which admit of a
     clear interpretation.

A digniori fieri debet denominatio et resolutio.

     Title and acquittal ought to proceed from the more worthy
     person.

A facto ad jus non datur consequentia.

     A fact does not necessarily constitute a right.

A non posse ad non esse sequitur argumentum necessarie negativè, licet
non affirmativè.

     From the impossibility of a thing to its nonentity, the
     argument or proof follows of necessity, negatively, though
     not affirmatively.

A principalioribus seu dignioribus est inchoandum.

     We must begin with the more noble, or more important
     matters; or in other words, we must attend to things of the
     greatest consequence.

A rescriptis valet argumentum.

     An argument or proof is valid, from a rescript or letter
     of a prince or emperor, making answers to petitions, or
     other applications; or more laconically, the king’s answer,
     wherein he signifies his pleasure, amounts to a law, and is
     not to be disputed.

A verbis legis non est recedendum.

     We must not depart from the letter of the law.

Ab assuetis non fit injuria.

     From customary treatment no injury happens; or habit is not
     an injury.

Absoluta sententia expositore non indiget.

     An absolute or perfect opinion or sentence, needs no
     expounder, exposition, or explanation.
\"\"\"

Question: \"\"\"What is the old latin legal principle behind 'A digniori fieri debet denominatio et resolutio'?\"\"\"
Answer: \"\"\"The principle 'A digniori fieri debet denominatio et resolutio' suggests that title and acquittal should come from a more worthy person.\"\"\"

### Response:
## Reasoning Steps:
Step 1. Formulate a plan to understand the meaning of 'A digniori fieri debet denominatio et resolutio' by defining it, then interpreting the definition in the context of law.
Step 2. Recall that the phrase 'A digniori fieri debet denominatio et resolutio' translates to "Title and acquittal ought to proceed from the more worthy person."
Step 3. Realize that this principle emphasizes the importance of the worthiness or merit of the individual in legal decisions related to titles and acquittals.
Step 4. Understand that this implies a belief that justice and legal rights should be administered by those who are most competent and deserving.
Step 5. Conclude that the old latin legal principle behind 'A digniori fieri debet denominatio et resolutio' is the emphasis on the importance of merit and worthiness in making legal decisions about titles and acquittals.

## Information:

Text the question and answer were sourced from (Carlos Mendez does not have access to this text, but does know its information; you can use insights from it, but don't mention "the text" by name):
\"\"\"
During the construction of the Panama Canal, a massive engineering feat completed in 1914, several challenges and achievements were noted. The canal, spanning approximately 50 miles, was designed to shorten the maritime route between the Atlantic and Pacific Oceans. Notably, the construction saw the use of innovative excavation techniques, with over 200 million cubic yards of earth removed. The project also faced significant health challenges, including combating malaria and yellow fever, which were overcome through extensive public health measures. The completion of the canal significantly impacted global trade, reducing the sea voyage from San Francisco to New York by around 8,000 miles.
\"\"\"

Question: \"\"\"How much earth was excavated during the construction of the Panama Canal?\"\"\"
Answer: \"\"\"Over 200 million cubic yards of earth were excavated during the construction of the Panama Canal, showcasing the scale of this massive engineering project.\"\"\"

### Response:
# Reasoning:
Step 1. Formulate a plan to answer the question about the amount of earth excavated during the Panama Canal construction.
Step 2. Recall that "how much earth was excavated" can be decently answered by stating the volume of earth removed.
Step 3. Recall that over 200 million cubic yards of earth were removed.
Step 4. Conclude that the answer to the question is over 200 million cubic yards.

## Information:

Text the question and answer were sourced from ({charname} does not have access to this text, but does know its information; you can use insights from it, but don't mention "the text" by name):
\"\"\"
{qatuple[2]}
\"\"\"

Question: \"\"\"{qatuple[0]}\"\"\"
Answer: \"\"\"{qatuple[1]}\"\"\"

### Response:
## Reasoning (only use as many logical steps as you must in order to solve the problem):
"""

    # Logical progression of steps that {charname} can use to answer the question
    completion = logic_llm(
        cot_prompt,
        max_tokens=4000,
        stop=["</s>", "# Input:"],
        echo=True,
        grammar=thought_plan_grammar,
        temperature=0.2,
    )["choices"][0]["text"]
    # print("COMPLETION:\n\n----------------------")
    # # print(completion)
    # print("\n------------------")

    # Extract plan
    response_pattern = re.compile(
        r"## Reasoning \(only use as many logical steps as you must in order to solve the problem\):\n(Step 1\..+)",
        re.IGNORECASE | re.DOTALL,
    )
    generation = response_pattern.search(completion).group(1)
    # print("GENERATION:\n\n-------------------\n\n", generation)

    return generation

if __name__ == "__main__":  # test
    logic_llm = Llama(
        model_path=LOGICAL_MODEL,
        n_gqa=8,
        offload_kqv=True,
        n_ctx=4096,
        n_gpu_layers=1000,
    )  # load the logical LLM and offload everything
    # Q0 is good q, bad a
    # q1 is good q, good a,
    # q2 is bad q, bad a,
    # q3 is iffy q, good a
    q_test = [
        (
            "Explain how our understanding of planetary motion has changed over time.",
            "The understanding has evolved from the Earth being stationary and at the centre of the universe, to it orbiting the sun in an elliptical path with other planets while still rotating on its axis.",
            "The story of our world is a story that is still very imperfectly known. A couple of hundred years ago men possessed the history of little more than the last three thousand years. What happened before that time was a matter of legend and speculation.  Over a large part of the civilized world it was believed and taught that the world had been created suddenly in 4004 B.C., though authorities differed as to whether this had occurred in the spring or autumn of that year. This fantastically precise misconception was based upon a too literal interpretation of the Hebrew Bible, and upon rather arbitrary theological assumptions connected therewith.  Such ideas have long since been abandoned by religious teachers, and it is universally recognized that the universe in which we live has to all appearances existed for an enormous period of time and possibly for endless time.  Of course there may be deception in these appearances, as a room may be made to seem endless by putting mirrors facing each other at either end. But that the universe in which we live has existed only for six or seven thousand years may be regarded as an altogether exploded idea.\n\nThe earth, as everybody knows nowadays, is a spheroid, a sphere slightly compressed, orange fashion, with a diameter of nearly 8,000 miles.  Its spherical shape has been known at least to a limited number of intelligent people for nearly 2,500 years, but before that time it was supposed to be flat, and various ideas which now seem fantastic were entertained about its relations to the sky and the stars and planets.  We know now that it rotates upon its axis (which is about 24 miles shorter than its equatorial diameter) every twenty-four hours, and that this is the cause of the alternations of day and night, that it circles about the sun in a slightly distorted and slowly variable oval path in a year. Its distance from the sun varies between ninety-one and a half millions at its nearest and ninety-four and a half million miles.",
        ),


import random
from .constants import names

def random_name():
    return random.choice(names)


from llama_cpp import LlamaGrammar

### A grammar that forces the model to generate correct character cards (with traits, names, everything)

single_turn_conversation_grammar = LlamaGrammar.from_string(
    r"""

# The root rule defines the structure of the dialogue
root ::= statement "\n\n" response "\n"

# Statement by Character Name 1
statement ::= [^\n]+ ":" [^\n]+

# Response by Character Name 2
response ::= [^\n]+ ":" [^\n]+

# Definition of a character name
character-name ::= word ("-" word)*
word ::= [A-Za-z]+
# Limiting to a maximum of six words
character-name ::= word | word word | word word word | word word word word | word word word word word | word word word word word word

# Definition of a dialogue line
dialogue-line ::= [^\n]+

"""
)

# question_grammar = LlamaGrammar.from_string(r"""# GBNF Grammar for Q&A Format with Flexible Punctuation

# root ::= answer
# answer ::= "Test"
# """)