Completed HW2

This commit is contained in:
Uzair Mohammed 2024-03-20 16:21:15 -07:00
parent 9f39068cc2
commit dfc0f0c7b9
27 changed files with 2188 additions and 59 deletions

BIN
hw2/gameTree.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
hw2/hw2.pdf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

26
hw2/ints/examples.py Normal file
View File

@ -0,0 +1,26 @@
from logic import *
# Sentence: "If it's rains, it's wet".
def rain_wet():
Rain = Atom('Rain') # whether it's raining
Wet = Atom('Wet') # whether it's wet
return Implies(Rain, Wet)
# Sentence: "There is a light that shines."
def light_shines():
def Light(x): return Atom('Light', x) # whether x is lit
def Shines(x): return Atom('Shines', x) # whether x is shining
return Exists('$x', And(Light('$x'), Shines('$x')))
# Defining Parent in terms of Child.
def parent_child():
def Parent(x, y): return Atom('Parent', x, y) # whether x has a parent y
def Child(x, y): return Atom('Child', x, y) # whether x has a child y
return Forall('$x', Forall('$y', Equiv(Parent('$x', '$y'), Child('$y', '$x'))))

109
hw2/ints/grader.py Normal file
View File

@ -0,0 +1,109 @@
#!/usr/bin/env python3
from logic import *
import pickle, gzip, os, random
import grader_util
grader = grader_util.Grader()
submission = grader.load('submission')
# name: name of this formula (used to load the models)
# predForm: the formula predicted in the submission
# preconditionForm: only consider models such that preconditionForm is true
def checkFormula(name, predForm, preconditionForm=None, handle_grader=True):
filename = os.path.join('models', name + '.pklz')
objects, targetModels = pickle.load(gzip.open(filename))
# If preconditionion exists, change the formula to
preconditionPredForm = And(preconditionForm, predForm) if preconditionForm else predForm
predModels = performModelChecking([preconditionPredForm], findAll=True, objects=objects)
ok = True
def hashkey(model): return tuple(sorted(str(atom) for atom in model))
targetModelSet = set(hashkey(model) for model in targetModels)
predModelSet = set(hashkey(model) for model in predModels)
for model in targetModels:
if hashkey(model) not in predModelSet:
if handle_grader:
grader.fail("Your formula (%s) says the following model is FALSE, but it should be TRUE:" % predForm)
ok = False
printModel(model)
return ok
for model in predModels:
if hashkey(model) not in targetModelSet:
if handle_grader:
grader.fail("Your formula (%s) says the following model is TRUE, but it should be FALSE:" % predForm)
ok = False
printModel(model)
return ok
if handle_grader:
grader.add_message('You matched the %d models' % len(targetModels))
grader.add_message('Example model: %s' % rstr(random.choice(targetModels)))
grader.assign_full_credit()
return ok
# name: name of this formula set (used to load the models)
# predForms: formulas predicted in the submission
# predQuery: query formula predicted in the submission
def addParts(name, numForms, predictionFunc):
# part is either an individual formula (0:numForms), all (combine everything)
def check(part):
predForms, predQuery = predictionFunc()
if len(predForms) < numForms:
grader.fail("Wanted %d formulas, but got %d formulas:" % (numForms, len(predForms)))
for form in predForms: print(('-', form))
return
if part == 'all':
checkFormula(name + '-all', AndList(predForms))
elif part == 'run':
# Actually run it on a knowledge base
kb = createModelCheckingKB()
# Need to tell the KB about the objects to do model checking
filename = os.path.join('models', name + '-all.pklz')
objects, targetModels = pickle.load(gzip.open(filename))
for obj in objects:
kb.tell(Atom('Object', obj))
# Add the formulas
for predForm in predForms:
response = kb.tell(predForm)
showKBResponse(response)
grader.require_is_true(response.status in [CONTINGENT, ENTAILMENT])
response = kb.ask(predQuery)
showKBResponse(response)
else: # Check the part-th formula
checkFormula(name + '-' + str(part), predForms[part])
def createCheck(part): return lambda : check(part) # To create closure
# run part-all once first for combined correctness, if true, trivially assign full score for all subparts
# this is to account for student adding formulas to the list in different orders but still get
# the combined preds correct.
all_is_correct = False
try:
predForms, predQuery = predictionFunc()
all_is_correct = checkFormula(name + '-all', AndList(predForms), handle_grader=False)
except BaseException:
pass
for part in list(range(numForms)) + ['all', 'run']:
if part == 'all':
description = 'test implementation of %s for %s' % (part, name)
elif part == 'run':
description = 'test implementation of %s for %s' % (part, name)
else:
description = 'test implementation of statement %s for %s' % (part, name)
if all_is_correct and not part in ['all', 'run']:
grader.add_basic_part(name + '-' + str(part), lambda : grader.assign_full_credit(), max_points=1, max_seconds=10000, description=description)
else:
grader.add_basic_part(name + '-' + str(part), createCheck(part), max_points=1, max_seconds=10000, description=description)
############################################################
# Problem 4: odd and even integers
# Add 5a-[0-5], 5a-all, 5a-run
addParts('4a', 6, submission.ints)
grader.grade()

448
hw2/ints/grader_util.py Normal file
View File

@ -0,0 +1,448 @@
"""
Library to do grading of Python programs.
Usage (see grader.py):
# create a grader
grader = Grader("Name of assignment")
# add a basic test
grader.addBasicPart(number, grade_func, max_points, max_seconds, description="a basic test")
# add a hidden test
grader.addHiddenPart(number, grade_func, max_points, max_seconds, description="a hidden test")
# add a manual grading part
grader.addManualPart(number, grade_func, max_points, description="written problem")
# run grading
grader.grade()
"""
import argparse
import datetime
import gc
import json
import os
import signal
import sys
import traceback
default_max_seconds = 5 # 5 second
TOLERANCE = 1e-4 # For measuring whether two floats are equal
BASIC_MODE = 'basic' # basic
AUTO_MODE = 'auto' # basic + hidden
ALL_MODE = 'all' # basic + hidden + manual
# When reporting stack traces as feedback, ignore parts specific to the grading
# system.
def is_traceback_item_grader(item):
return item[0].endswith('graderUtil.py')
def is_collection(x):
return isinstance(x, list) or isinstance(x, tuple)
# Return whether two answers are equal.
def is_equal(true_answer, pred_answer, tolerance=TOLERANCE):
# Handle floats specially
if isinstance(true_answer, float) or isinstance(pred_answer, float):
return abs(true_answer - pred_answer) < tolerance
# Recurse on collections to deal with floats inside them
if is_collection(true_answer) and is_collection(pred_answer) and len(true_answer) == len(pred_answer):
for a, b in zip(true_answer, pred_answer):
if not is_equal(a, b):
return False
return True
if isinstance(true_answer, dict) and isinstance(pred_answer, dict):
if len(true_answer) != len(pred_answer):
return False
for k, v in list(true_answer.items()):
if not is_equal(pred_answer.get(k), v):
return False
return True
# Numpy array comparison
if type(true_answer).__name__ == 'ndarray':
import numpy as np
if isinstance(true_answer, np.ndarray) and isinstance(pred_answer, np.ndarray):
if true_answer.shape != pred_answer.shape:
return False
for a, b in zip(true_answer, pred_answer):
if not is_equal(a, b):
return False
return True
# Do normal comparison
return true_answer == pred_answer
# Run a function, timing out after max_seconds.
class TimeoutFunctionException(Exception):
pass
class TimeoutFunction:
def __init__(self, function, max_seconds):
self.max_seconds = max_seconds
self.function = function
@staticmethod
def handle_max_seconds(signum, frame):
print('TIMEOUT!')
raise TimeoutFunctionException()
def __call__(self, *args):
if os.name == 'nt':
# Windows does not have signal.SIGALRM
# Will not stop after max_seconds second but can still throw an exception
time_start = datetime.datetime.now()
result = self.function(*args)
time_end = datetime.datetime.now()
if time_end - time_start > datetime.timedelta(seconds=self.max_seconds + 1):
raise TimeoutFunctionException()
return result
# End modification for Windows here
signal.signal(signal.SIGALRM, self.handle_max_seconds)
signal.alarm(self.max_seconds + 1)
result = self.function(*args)
signal.alarm(0)
return result
class Part:
def __init__(self, number, grade_func, max_points, max_seconds, extra_credit, description, basic):
if not isinstance(number, str):
raise Exception("Invalid number: %s" % number)
if grade_func is not None and not callable(grade_func):
raise Exception("Invalid grade_func: %s" % grade_func)
if not isinstance(max_points, int) and not isinstance(max_points, float):
raise Exception("Invalid max_points: %s" % max_points)
if max_seconds is not None and not isinstance(max_seconds, int):
raise Exception("Invalid max_seconds: %s" % max_seconds)
if not description:
print('ERROR: description required for part {}'.format(number))
# Specification of part
self.number = number # Unique identifier for this part.
self.description = description # Description of this part
self.grade_func = grade_func # Function to call to do grading
self.max_points = max_points # Maximum number of points attainable on this part
self.max_seconds = max_seconds # Maximum allowed time that the student's code can take (in seconds)
self.extra_credit = extra_credit # Whether this is an extra credit problem
self.basic = basic
# Grading the part
self.points = 0
self.side = None # Side information
self.seconds = 0
self.messages = []
self.failed = False
def fail(self):
self.failed = True
def is_basic(self):
return self.grade_func is not None and self.basic
def is_hidden(self):
return self.grade_func is not None and not self.basic
def is_auto(self):
return self.grade_func is not None
def is_manual(self):
return self.grade_func is None
class Grader:
def __init__(self, args=None):
if args is None:
args = sys.argv
self.parts = [] # Parts (to be added)
self.useSolution = False # Set to true if we are actually evaluating the hidden test cases
parser = argparse.ArgumentParser()
parser.add_argument('--js', action='store_true', help='Write JS file with information about this assignment')
parser.add_argument('--json', action='store_true',
help='Write JSON file with information about this assignment')
parser.add_argument('--summary', action='store_true', help='Don\'t actually run code')
parser.add_argument('remainder', nargs=argparse.REMAINDER)
self.params = parser.parse_args(args[1:])
args = self.params.remainder
if len(args) < 1:
self.mode = AUTO_MODE
self.selectedPartName = None
else:
if args[0] in [BASIC_MODE, AUTO_MODE, ALL_MODE]:
self.mode = args[0]
self.selectedPartName = None
else:
self.mode = AUTO_MODE
self.selectedPartName = args[0]
self.messages = [] # General messages
self.currentPart = None # Which part we're grading
self.fatalError = False # Set this if we should just stop immediately
def add_basic_part(self, number, grade_func, max_points=1, max_seconds=default_max_seconds, extra_credit=False,
description=""):
"""Add a basic test case. The test will be visible to students."""
self.assert_new_number(number)
part = Part(number, grade_func, max_points, max_seconds, extra_credit, description, basic=True)
self.parts.append(part)
def add_hidden_part(self, number, grade_func, max_points=1, max_seconds=default_max_seconds, extra_credit=False,
description=""):
"""Add a hidden test case. The output should NOT be visible to students
and so should be inside a BEGIN_HIDE block."""
self.assert_new_number(number)
part = Part(number, grade_func, max_points, max_seconds, extra_credit, description, basic=False)
self.parts.append(part)
def add_manual_part(self, number, max_points, extra_credit=False, description=""):
"""Add a manual part."""
self.assert_new_number(number)
part = Part(number, None, max_points, None, extra_credit, description, basic=False)
self.parts.append(part)
def assert_new_number(self, number):
if number in [part.number for part in self.parts]:
raise Exception("Part number %s already exists" % number)
# Try to load the module (submission from student).
def load(self, module_name):
try:
return __import__(module_name)
except Exception as e:
self.fail("Threw exception when importing '%s': %s" % (module_name, e))
self.fatalError = True
return None
except:
self.fail("Threw exception when importing '%s'" % module_name)
self.fatalError = True
return None
def grade_part(self, part):
print('----- START PART %s%s: %s' % (
part.number, ' (extra credit)' if part.extra_credit else '', part.description))
self.currentPart = part
start_time = datetime.datetime.now()
try:
TimeoutFunction(part.grade_func, part.max_seconds)() # Call the part's function
except KeyboardInterrupt:
raise
except MemoryError:
signal.alarm(0)
gc.collect()
self.fail('Memory limit exceeded.')
except TimeoutFunctionException:
signal.alarm(0)
self.fail('Time limit (%s seconds) exceeded.' % part.max_seconds)
except Exception as e:
signal.alarm(0)
self.fail('Exception thrown: %s -- %s' % (str(type(e)), str(e)))
self.print_exception()
except SystemExit:
# Catch SystemExit raised by exit(), quit() or sys.exit()
# This class is not a subclass of Exception and we don't
# expect students to raise it.
self.fail('Unexpected exit.')
self.print_exception()
end_time = datetime.datetime.now()
part.seconds = (end_time - start_time).seconds
###### quick fix to pacman problem 4 ######
if part.seconds > part.max_seconds:
signal.alarm(0)
self.fail('Time limit (%s seconds) exceeded.' % part.max_seconds)
###### quick fix to pacman problem 4 ######
if part.is_hidden() and not self.useSolution:
display_points = '???/%s points (hidden test ungraded)' % part.max_points
else:
display_points = '%s/%s points' % (part.points, part.max_points)
print('----- END PART %s [%s]' % (
part.number, display_points))
print()
def get_selected_parts(self):
parts = []
for part in self.parts:
if self.selectedPartName is not None and self.selectedPartName != part.number:
continue
if self.mode == BASIC_MODE:
if part.is_basic():
parts.append(part)
elif self.mode == AUTO_MODE:
if part.is_auto():
parts.append(part)
elif self.mode == ALL_MODE:
parts.append(part)
else:
raise Exception("Invalid mode: {}".format(self.mode))
return parts
def grade(self):
parts = self.get_selected_parts()
result = {'mode': self.mode}
# Grade it!
if not self.params.summary and not self.fatalError:
print('========== START GRADING')
for part in parts:
self.grade_part(part)
# When students have it (not useSolution), only include basic tests.
active_parts = [part for part in parts if self.useSolution or part.basic]
total_points = sum(part.points for part in active_parts if not part.extra_credit)
extra_credit = sum(part.points for part in active_parts if part.extra_credit)
max_total_points = sum(part.max_points for part in active_parts if not part.extra_credit)
max_extra_credit = sum(part.max_points for part in active_parts if part.extra_credit)
print('========== END GRADING [%s/%s points + %s/%s extra credit]' %
(total_points, max_total_points, extra_credit, max_extra_credit))
result_parts = []
leaderboard = []
for part in parts:
r = {'number': part.number, 'name': part.description}
if self.params.summary:
# Just print out specification of the part
r['description'] = part.description
r['max_seconds'] = part.max_seconds
r['max_points'] = part.max_points
r['extra_credit'] = part.extra_credit
r['basic'] = part.basic
else:
r['score'] = part.points
# Force max_score to be 0 for extra credits for displaying correct total points on Gradescope
r['max_score'] = 0 if (part.extra_credit and self.mode == AUTO_MODE) else part.max_points
r["visibility"] = "after_published" if part.is_hidden() else "visible"
r['seconds'] = part.seconds
if part.side is not None:
r['side'] = part.side
r['output'] = "\n".join(part.messages)
if part.side is not None:
for k in part.side:
leaderboard.append({"name": k, "value": part.side[k]})
result_parts.append(r)
result['tests'] = result_parts
result['leaderboard'] = leaderboard
self.output(self.mode, result)
def display(name, select_extra_credit):
parts_to_display = [p for p in self.parts if p.extra_credit == select_extra_credit]
max_basic_points = sum(p.max_points for p in parts_to_display if p.is_basic())
max_hidden_points = sum(p.max_points for p in parts_to_display if p.is_hidden())
max_manual_points = sum(p.max_points for p in parts_to_display if p.is_manual())
max_total_points_found = max_basic_points + max_hidden_points + max_manual_points
print("Total %s (basic auto/coding + hidden auto/coding + manual/written): %d + %d + %d = %d" %
(name, max_basic_points, max_hidden_points, max_manual_points, max_total_points_found))
if not select_extra_credit and max_total_points_found != 75:
print('WARNING: max_total_points = {} is not 75'.format(max_total_points_found))
if self.params.summary:
display('points', False)
display('extra credit', True)
def output(self, mode, result):
if self.params.json:
path = 'grader-{}.json'.format(mode)
with open(path, 'w') as out:
print(json.dumps(result), file=out)
print('Wrote to %s' % path)
if self.params.js:
path = 'grader-{}.js'.format(mode)
with open(path, 'w') as out:
print('var ' + mode + 'Result = ' + json.dumps(result) + ';', file=out)
print('Wrote to %s' % path)
# Called by the grader to modify state of the current part
def add_points(self, amt):
self.currentPart.points += amt
def assign_full_credit(self):
if not self.currentPart.failed:
self.currentPart.points = self.currentPart.max_points
return True
def assign_partial_credit(self, credit):
self.currentPart.points = credit
return True
def set_side(self, side):
self.currentPart.side = side
@staticmethod
def truncate_string(string, length=200):
if len(string) <= length:
return string
else:
return string[:length] + '...'
def require_is_numeric(self, answer):
if isinstance(answer, int) or isinstance(answer, float):
return self.assign_full_credit()
else:
return self.fail("Expected either int or float, but got '%s'" % self.truncate_string(answer))
def require_is_one_of(self, true_answers, pred_answer):
if pred_answer in true_answers:
return self.assign_full_credit()
else:
return self.fail("Expected one of %s, but got '%s'" % (
self.truncate_string(true_answers), self.truncate_string(pred_answer)))
def require_is_equal(self, true_answer, pred_answer, tolerance=TOLERANCE):
if is_equal(true_answer, pred_answer, tolerance):
return self.assign_full_credit()
else:
return self.fail("Expected '%s', but got '%s'" % (
self.truncate_string(str(true_answer)), self.truncate_string(str(pred_answer))))
def require_is_less_than(self, less_than_quantity, pred_answer):
if pred_answer < less_than_quantity:
return self.assign_full_credit()
else:
return self.fail("Expected to be < %f, but got %f" % (less_than_quantity, pred_answer))
def require_is_greater_than(self, greater_than_quantity, pred_answer):
if pred_answer > greater_than_quantity:
return self.assign_full_credit()
else:
return self.fail("Expected to be > %f, but got %f" %
(greater_than_quantity, pred_answer))
def require_is_true(self, pred_answer):
if pred_answer:
return self.assign_full_credit()
else:
return self.fail("Expected to be true, but got false")
def fail(self, message):
print('FAIL:', message)
self.add_message(message)
if self.currentPart:
self.currentPart.points = 0
self.currentPart.fail()
return False
def print_exception(self):
tb = [item for item in traceback.extract_tb(sys.exc_info()[2]) if not is_traceback_item_grader(item)]
for item in traceback.format_list(tb):
self.fail('%s' % item)
def add_message(self, message):
if not self.useSolution:
print(message)
if self.currentPart:
self.currentPart.messages.append(message)
else:
self.messages.append(message)

1084
hw2/ints/logic.py Normal file

File diff suppressed because it is too large Load Diff

BIN
hw2/ints/models/4a-0.pklz Normal file

Binary file not shown.

BIN
hw2/ints/models/4a-1.pklz Normal file

Binary file not shown.

BIN
hw2/ints/models/4a-2.pklz Normal file

Binary file not shown.

BIN
hw2/ints/models/4a-3.pklz Normal file

Binary file not shown.

BIN
hw2/ints/models/4a-4.pklz Normal file

Binary file not shown.

BIN
hw2/ints/models/4a-5.pklz Normal file

Binary file not shown.

BIN
hw2/ints/models/4a-all.pklz Normal file

Binary file not shown.

42
hw2/ints/submission.py Normal file
View File

@ -0,0 +1,42 @@
############################################################
# Problem 4: Odd and even integers
from typing import Tuple, List
from logic import *
# Return the following 6 laws. Be sure your formulas are exactly in the order specified.
# 0. Each number $x$ has exactly one successor, which is not equal to $x$.
# 1. Each number is either even or odd, but not both.
# 2. The successor number of an even number is odd.
# 3. The successor number of an odd number is even.
# 4. For every number $x$, the successor of $x$ is larger than $x$.
# 5. Larger is a transitive property: if $x$ is larger than $y$ and $y$ is
# larger than $z$, then $x$ is larger than $z$.
# Query: For each number, there exists an even number larger than it.
def ints() -> Tuple[List[Formula], Formula]:
def Even(x): return Atom('Even', x) # whether x is even
def Odd(x): return Atom('Odd', x) # whether x is odd
def Successor(x, y): return Atom('Successor', x, y) # whether x's successor is y
def Larger(x, y): return Atom('Larger', x, y) # whether x is larger than y
# Note: all objects are numbers, so we don't need to define Number as an
# explicit predicate.
#
# Note: pay attention to the order of arguments of Successor and Larger.
# Populate `formulas` with the 6 laws above.
#
# Hint: You might want to use the Equals predicate, defined in logic.py. This
# predicate is used to assert that two objects are the same.
formulas = []
formulas.append(Forall('$x', Exists('$y', And(Successor('$x', '$y'), And(Not(Equals('$x', '$y')), Forall('$z', Implies(Not(Equals('$z', '$y')), Not(Successor('$x', '$z')))))))))
formulas.append(Forall('$x', Or(And(Even('$x'), Not(Odd('$x'))), And(Odd('$x'), Not(Even('$x'))))))
formulas.append(Forall('$x', Implies(Even('$x'), Exists('$y', Odd(Successor('$x', '$y'))))))
formulas.append(Forall('$x', Implies(Odd('$x'), Exists('$y', Even(Successor('$x', '$y'))))))
formulas.append(Forall('$x', Implies(Exists('$y', Successor('$x', '$y')), Larger('$y', '$x'))))
formulas.append(Forall('$x', Forall('$y', Forall('$z', Implies(And(Larger('$x', '$y'), Larger('$y', '$z')), Larger('$x', '$z'))))))
query = Forall('$x', Exists('$y', And(Even('$y'), Larger('$y', '$x'))))
return formulas, query

Binary file not shown.

260
hw2/knights/logic.py Normal file
View File

@ -0,0 +1,260 @@
class Sentence:
def evaluate(self, model):
"""Evaluates the logical sentence."""
raise Exception("nothing to evaluate")
def formula(self):
"""Returns string formula representing logical sentence."""
return ""
def symbols(self):
"""Returns a set of all symbols in the logical sentence."""
return set()
@classmethod
def validate(cls, sentence):
if not isinstance(sentence, Sentence):
raise TypeError("must be a logical sentence")
@classmethod
def parenthesize(cls, s):
"""Parenthesizes an expression if not already parenthesized."""
def balanced(s):
"""Checks if a string has balanced parentheses."""
count = 0
for c in s:
if c == "(":
count += 1
elif c == ")":
if count <= 0:
return False
count -= 1
return count == 0
if not len(s) or s.isalpha() or (
s[0] == "(" and s[-1] == ")" and balanced(s[1:-1])
):
return s
else:
return f"({s})"
class Symbol(Sentence):
def __init__(self, name):
self.name = name
def __eq__(self, other):
return isinstance(other, Symbol) and self.name == other.name
def __hash__(self):
return hash(("symbol", self.name))
def __repr__(self):
return self.name
def evaluate(self, model):
try:
return bool(model[self.name])
except KeyError:
raise Exception(f"variable {self.name} not in model")
def formula(self):
return self.name
def symbols(self):
return {self.name}
class Not(Sentence):
def __init__(self, operand):
Sentence.validate(operand)
self.operand = operand
def __eq__(self, other):
return isinstance(other, Not) and self.operand == other.operand
def __hash__(self):
return hash(("not", hash(self.operand)))
def __repr__(self):
return f"Not({self.operand})"
def evaluate(self, model):
return not self.operand.evaluate(model)
def formula(self):
return "¬" + Sentence.parenthesize(self.operand.formula())
def symbols(self):
return self.operand.symbols()
class And(Sentence):
def __init__(self, *conjuncts):
for conjunct in conjuncts:
Sentence.validate(conjunct)
self.conjuncts = list(conjuncts)
def __eq__(self, other):
return isinstance(other, And) and self.conjuncts == other.conjuncts
def __hash__(self):
return hash(
("and", tuple(hash(conjunct) for conjunct in self.conjuncts))
)
def __repr__(self):
conjunctions = ", ".join(
[str(conjunct) for conjunct in self.conjuncts]
)
return f"And({conjunctions})"
def add(self, conjunct):
Sentence.validate(conjunct)
self.conjuncts.append(conjunct)
def evaluate(self, model):
return all(conjunct.evaluate(model) for conjunct in self.conjuncts)
def formula(self):
if len(self.conjuncts) == 1:
return self.conjuncts[0].formula()
return "".join([Sentence.parenthesize(conjunct.formula())
for conjunct in self.conjuncts])
def symbols(self):
return set.union(*[conjunct.symbols() for conjunct in self.conjuncts])
class Or(Sentence):
def __init__(self, *disjuncts):
for disjunct in disjuncts:
Sentence.validate(disjunct)
self.disjuncts = list(disjuncts)
def __eq__(self, other):
return isinstance(other, Or) and self.disjuncts == other.disjuncts
def __hash__(self):
return hash(
("or", tuple(hash(disjunct) for disjunct in self.disjuncts))
)
def __repr__(self):
disjuncts = ", ".join([str(disjunct) for disjunct in self.disjuncts])
return f"Or({disjuncts})"
def evaluate(self, model):
return any(disjunct.evaluate(model) for disjunct in self.disjuncts)
def formula(self):
if len(self.disjuncts) == 1:
return self.disjuncts[0].formula()
return " ".join([Sentence.parenthesize(disjunct.formula())
for disjunct in self.disjuncts])
def symbols(self):
return set.union(*[disjunct.symbols() for disjunct in self.disjuncts])
class Implication(Sentence):
def __init__(self, antecedent, consequent):
Sentence.validate(antecedent)
Sentence.validate(consequent)
self.antecedent = antecedent
self.consequent = consequent
def __eq__(self, other):
return (isinstance(other, Implication)
and self.antecedent == other.antecedent
and self.consequent == other.consequent)
def __hash__(self):
return hash(("implies", hash(self.antecedent), hash(self.consequent)))
def __repr__(self):
return f"Implication({self.antecedent}, {self.consequent})"
def evaluate(self, model):
return ((not self.antecedent.evaluate(model))
or self.consequent.evaluate(model))
def formula(self):
antecedent = Sentence.parenthesize(self.antecedent.formula())
consequent = Sentence.parenthesize(self.consequent.formula())
return f"{antecedent} => {consequent}"
def symbols(self):
return set.union(self.antecedent.symbols(), self.consequent.symbols())
class Biconditional(Sentence):
def __init__(self, left, right):
Sentence.validate(left)
Sentence.validate(right)
self.left = left
self.right = right
def __eq__(self, other):
return (isinstance(other, Biconditional)
and self.left == other.left
and self.right == other.right)
def __hash__(self):
return hash(("biconditional", hash(self.left), hash(self.right)))
def __repr__(self):
return f"Biconditional({self.left}, {self.right})"
def evaluate(self, model):
return ((self.left.evaluate(model)
and self.right.evaluate(model))
or (not self.left.evaluate(model)
and not self.right.evaluate(model)))
def formula(self):
left = Sentence.parenthesize(str(self.left))
right = Sentence.parenthesize(str(self.right))
return f"{left} <=> {right}"
def symbols(self):
return set.union(self.left.symbols(), self.right.symbols())
def model_check(knowledge, query):
"""Checks if knowledge base entails query."""
def check_all(knowledge, query, symbols, model):
"""Checks if knowledge base entails query, given a particular model."""
# If model has an assignment for each symbol
if not symbols:
# If knowledge base is true in model, then query must also be true
if knowledge.evaluate(model):
return query.evaluate(model)
return True
else:
# Choose one of the remaining unused symbols
remaining = symbols.copy()
p = remaining.pop()
# Create a model where the symbol is true
model_true = model.copy()
model_true[p] = True
# Create a model where the symbol is false
model_false = model.copy()
model_false[p] = False
# Ensure entailment holds in both models
return (check_all(knowledge, query, remaining, model_true) and
check_all(knowledge, query, remaining, model_false))
# Get all symbols in both knowledge and query
symbols = set.union(knowledge.symbols(), query.symbols())
# Check that knowledge entails query
return check_all(knowledge, query, symbols, dict())

82
hw2/knights/puzzle.py Normal file
View File

@ -0,0 +1,82 @@
from logic import *
AKnight = Symbol("A is a Knight")
AKnave = Symbol("A is a Knave")
BKnight = Symbol("B is a Knight")
BKnave = Symbol("B is a Knave")
CKnight = Symbol("C is a Knight")
CKnave = Symbol("C is a Knave")
# Puzzle 0
# A says "I am both a knight and a knave."
knowledge0 = And(
Or(AKnight, AKnave), # A is either a knight or a knave
Not(And(AKnight, AKnave)), # A cannot be both a knight and a knave
Biconditional(AKnight, And(AKnight, AKnave)) # If A is a knight, then the statement is true; if A is a knave, the statement is false
)
# Puzzle 1
# A says "We are both knaves."
# B says nothing.
knowledge1 = And(
Or(AKnight, AKnave), # A is either a knight or a knave
Or(BKnight, BKnave), # B is either a knight or a knave
Not(And(AKnight, AKnave)), # A cannot be both a knight and a knave
Not(And(BKnight, BKnave)), # B cannot be both a knight and a knave
Biconditional(AKnight, And(AKnave, BKnave)), # If A is a knight, then the statement is true; if A is a knave, the statement is false
Biconditional(AKnave, Not(And(AKnave, BKnave))) # If A is a knave, then the opposite of the statement is true
)
# Puzzle 2
# A says "We are the same kind."
# B says "We are of different kinds."
knowledge2 = And(
Or(AKnight, AKnave), # A is either a knight or a knave
Or(BKnight, BKnave), # B is either a knight or a knave
Not(And(AKnight, AKnave)), # A cannot be both a knight and a knave
Not(And(BKnight, BKnave)), # B cannot be both a knight and a knave
Biconditional(AKnight, Or(And(AKnight, BKnight), And(AKnave, BKnave))), # If A is a knight, then A's statement is true; if A is a knave, then A's statement is false
Biconditional(BKnight, Or(And(AKnight, BKnave), And(AKnave, BKnight))) # If B is a knight, then B's statement is true; if B is a knave, then B's statement is false
)
# Puzzle 3
# A says either "I am a knight." or "I am a knave.", but you don't know which.
# B says "A said 'I am a knave'."
# B says "C is a knave."
# C says "A is a knight."
knowledge3 = And(
Or(AKnight, AKnave),
Or(BKnight, BKnave),
Or(CKnight, CKnave),
Biconditional(AKnight, Not(AKnave)),
Biconditional(BKnight, Not(BKnave)),
Biconditional(CKnight, Not(CKnave)),
Implication(BKnight, Not(AKnave)),
Implication(BKnave, And(AKnight, CKnight)),
Implication(AKnight, CKnight),
Implication(AKnight, Not(BKnight))
)
def main():
symbols = [AKnight, AKnave, BKnight, BKnave, CKnight, CKnave]
puzzles = [
("Puzzle 0", knowledge0),
("Puzzle 1", knowledge1),
("Puzzle 2", knowledge2),
("Puzzle 3", knowledge3)
]
for puzzle, knowledge in puzzles:
print(puzzle)
if len(knowledge.conjuncts) == 0:
print(" Not yet implemented.")
else:
for symbol in symbols:
if model_check(knowledge, symbol):
print(f" {symbol}")
if __name__ == "__main__":
main()

View File

@ -10,4 +10,8 @@
\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Grid City}{7}{}\protected@file@percent } \@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Grid City}{7}{}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Six Degrees}{8}{}\protected@file@percent } \@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Six Degrees}{8}{}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Tic Tac Toe}{8}{}\protected@file@percent } \@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Tic Tac Toe}{8}{}\protected@file@percent }
\gdef \@abspage@last{9} \@writefile{toc}{\contentsline {section}{\numberline {2}Homework 2}{8}{}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Cake}{8}{}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Knights and Knaves}{10}{}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Odds and Evens}{10}{}\protected@file@percent }
\gdef \@abspage@last{11}

View File

@ -1,8 +1,8 @@
# Fdb version 4 # Fdb version 4
["pdflatex"] 1709000449.89094 "c:/Users/uzair/OneDrive/Documents/CSC 665/main.tex" "main.pdf" "main" 1709000450.74539 0 ["pdflatex"] 1710976757.77869 "c:/Users/uzair/OneDrive/Documents/Programming/classes/spring-2024/CSC_665_Homework/main.tex" "main.pdf" "main" 1710976758.61168 0
"C:/Users/uzair/AppData/Local/MiKTeX/fonts/map/pdftex/pdftex.map" 1707457733 80909 eab91d9745dd2edfd62a31d53cd5fe15 "" "C:/Users/uzair/AppData/Local/MiKTeX/fonts/map/pdftex/pdftex.map" 1710451113 80909 eab91d9745dd2edfd62a31d53cd5fe15 ""
"C:/Users/uzair/AppData/Local/MiKTeX/fonts/pk/ljfour/jknappen/ec/dpi600/tcrm1000.pk" 1707288887 11548 1854d2b3451e3d517cccd4e0b4daead1 "" "C:/Users/uzair/AppData/Local/MiKTeX/fonts/pk/ljfour/jknappen/ec/dpi600/tcrm1000.pk" 1710450570 11548 75f9244b55c9330932ad6d45f833429f ""
"C:/Users/uzair/AppData/Local/MiKTeX/miktex/data/le/pdftex/pdflatex.fmt" 1707288883 24210786 eea8c83a2618bf979528f763e32e98c9 "" "C:/Users/uzair/AppData/Local/MiKTeX/miktex/data/le/pdftex/pdflatex.fmt" 1710872278 24233103 0233cc216d9fba92d9492b92406b1361 ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/tfm/jknappen/ec/tcrm1000.tfm" 993062508 1436 c7f957a372ef2fbe93c0982f96625e12 "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/tfm/jknappen/ec/tcrm1000.tfm" 993062508 1436 c7f957a372ef2fbe93c0982f96625e12 ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1233951848 1004 54797486969f23fa377b128694d548df "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1233951848 1004 54797486969f23fa377b128694d548df ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/tfm/public/amsfonts/symbols/msam10.tfm" 1233951854 916 f87d7c45f9c908e672703b83b72241a3 "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/tfm/public/amsfonts/symbols/msam10.tfm" 1233951854 916 f87d7c45f9c908e672703b83b72241a3 ""
@ -49,15 +49,16 @@
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/graphics/graphicx.sty" 1665067579 8010 a8d949cbdbc5c983593827c9eec252e1 "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/graphics/graphicx.sty" 1665067579 8010 a8d949cbdbc5c983593827c9eec252e1 ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/graphics/keyval.sty" 1665067579 2671 7e67d78d9b88c845599a85b2d41f2e39 "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/graphics/keyval.sty" 1665067579 2671 7e67d78d9b88c845599a85b2d41f2e39 ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/graphics/trig.sty" 1665067579 4023 293ea1c16429fc0c4cf605f4da1791a9 "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/graphics/trig.sty" 1665067579 4023 293ea1c16429fc0c4cf605f4da1791a9 ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/l3backend/l3backend-pdftex.def" 1704400941 30006 57b07afb710ee2f649c65cfbafda39c1 "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/l3backend/l3backend-pdftex.def" 1708427688 30006 3d512c0edd558928ddea1690180ef77e ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/mathtools/mathtools.sty" 1656514886 62269 5c1837a5bc5db4c0d255eedc225ca44b "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/mathtools/mathtools.sty" 1656514886 62269 5c1837a5bc5db4c0d255eedc225ca44b ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/mathtools/mhsetup.sty" 1656514886 5582 a43dedf8e5ec418356f1e9dfe5d29fc3 "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/mathtools/mhsetup.sty" 1656514886 5582 a43dedf8e5ec418356f1e9dfe5d29fc3 ""
"C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/tools/calc.sty" 1700599895 10214 547fd4d29642cb7c80bf54b49d447f01 "" "C:/Users/uzair/AppData/Local/Programs/MiKTeX/tex/latex/tools/calc.sty" 1700599895 10214 547fd4d29642cb7c80bf54b49d447f01 ""
"c:/Users/uzair/OneDrive/Documents/CSC 665/main.tex" 1709000447 12730 ae20bfc5e0f04caa86c900106aea97ed "" "c:/Users/uzair/OneDrive/Documents/Programming/classes/spring-2024/CSC_665_Homework/main.tex" 1710976753 15294 eefeb5115f03a7d6344da121e4de1ec8 ""
"main.aux" 1709000450 1087 ba931f15dd3503a818797c381a180181 "pdflatex" "hw2/gameTree.png" 1710872445 51736 b13904e696801b947e455a901505f683 ""
"main.tex" 1709000447 12730 ae20bfc5e0f04caa86c900106aea97ed "" "main.aux" 1710976758 1503 e54afcc87f6e15c8bb521b6c8a85270b "pdflatex"
"titlePage.aux" 1709000450 456 c979711f53deacf2b09031977e556db8 "pdflatex" "main.tex" 1710976753 15294 eefeb5115f03a7d6344da121e4de1ec8 ""
"titlePage.tex" 1707288498 394 ccdbd50244b3194dbad72dd1c7995bf0 "" "titlePage.aux" 1710976758 456 c979711f53deacf2b09031977e556db8 "pdflatex"
"titlePage.tex" 1710042044 407 ccdbd50244b3194dbad72dd1c7995bf0 ""
(generated) (generated)
"main.aux" "main.aux"
"main.log" "main.log"

View File

@ -1,6 +1,6 @@
PWD c:\Users\uzair\OneDrive\Documents\CSC 665 PWD c:\Users\uzair\OneDrive\Documents\Programming\classes\spring-2024\CSC_665_Homework
INPUT C:\Users\uzair\AppData\Local\MiKTeX\miktex\data\le\pdftex\pdflatex.fmt INPUT C:\Users\uzair\AppData\Local\MiKTeX\miktex\data\le\pdftex\pdflatex.fmt
INPUT c:\Users\uzair\OneDrive\Documents\CSC 665\main.tex INPUT c:\Users\uzair\OneDrive\Documents\Programming\classes\spring-2024\CSC_665_Homework\main.tex
OUTPUT main.log OUTPUT main.log
INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex\latex\base\article.cls INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex\latex\base\article.cls
INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex\latex\base\article.cls INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex\latex\base\article.cls
@ -91,6 +91,13 @@ INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\fonts\tfm\public\cm\cmti10.tf
INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\fonts\tfm\public\cm\cmbx12.tfm INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\fonts\tfm\public\cm\cmbx12.tfm
INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\fonts\tfm\jknappen\ec\tcrm1000.tfm INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\fonts\tfm\jknappen\ec\tcrm1000.tfm
INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\fonts\tfm\public\cm\cmbx10.tfm INPUT C:\Users\uzair\AppData\Local\Programs\MiKTeX\fonts\tfm\public\cm\cmbx10.tfm
INPUT .\hw2\gameTree.png
INPUT .\hw2\gameTree.png
INPUT .\hw2\gameTree.png
INPUT .\hw2\gameTree.png
INPUT .\hw2\gameTree.png
INPUT .\hw2\gameTree.png
INPUT .\hw2\gameTree.png
INPUT main.aux INPUT main.aux
INPUT .\titlePage.aux INPUT .\titlePage.aux
INPUT .\titlePage.aux INPUT .\titlePage.aux

View File

@ -1,25 +1,25 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (MiKTeX 24.1) (preloaded format=pdflatex 2024.2.6) 26 FEB 2024 18:20 This is pdfTeX, Version 3.141592653-2.6-1.40.26 (MiKTeX 24.3) (preloaded format=pdflatex 2024.3.19) 20 MAR 2024 16:19
entering extended mode entering extended mode
restricted \write18 enabled. restricted \write18 enabled.
file:line:error style messages enabled. file:line:error style messages enabled.
%&-line parsing enabled. %&-line parsing enabled.
**"c:/Users/uzair/OneDrive/Documents/CSC 665/main.tex" **c:/Users/uzair/OneDrive/Documents/Programming/classes/spring-2024/CSC_665_Homework/main.tex
(c:/Users/uzair/OneDrive/Documents/CSC 665/main.tex (c:/Users/uzair/OneDrive/Documents/Programming/classes/spring-2024/CSC_665_Homework/main.tex
LaTeX2e <2023-11-01> patch level 1 LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-01-22> L3 programming layer <2024-02-20>
(C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/base\article.cls (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/base\article.cls
Document Class: article 2023/05/17 v1.4n Standard LaTeX document class Document Class: article 2023/05/17 v1.4n Standard LaTeX document class
(C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/base\size10.clo (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/base\size10.clo
File: size10.clo 2023/05/17 v1.4n Standard LaTeX file (size option) File: size10.clo 2023/05/17 v1.4n Standard LaTeX file (size option)
) )
\c@part=\count187 \c@part=\count188
\c@section=\count188 \c@section=\count189
\c@subsection=\count189 \c@subsection=\count190
\c@subsubsection=\count190 \c@subsubsection=\count191
\c@paragraph=\count191 \c@paragraph=\count192
\c@subparagraph=\count192 \c@subparagraph=\count193
\c@figure=\count193 \c@figure=\count194
\c@table=\count194 \c@table=\count195
\abovecaptionskip=\skip48 \abovecaptionskip=\skip48
\belowcaptionskip=\skip49 \belowcaptionskip=\skip49
\bibindent=\dimen140 \bibindent=\dimen140
@ -40,14 +40,14 @@ Package: amsbsy 1999/11/29 v1.2d Bold Symbols
) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/amsmath\amsopn.sty ) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/amsmath\amsopn.sty
Package: amsopn 2022/04/08 v2.04 operator names Package: amsopn 2022/04/08 v2.04 operator names
) )
\inf@bad=\count195 \inf@bad=\count196
LaTeX Info: Redefining \frac on input line 234. LaTeX Info: Redefining \frac on input line 234.
\uproot@=\count196 \uproot@=\count197
\leftroot@=\count197 \leftroot@=\count198
LaTeX Info: Redefining \overline on input line 399. LaTeX Info: Redefining \overline on input line 399.
LaTeX Info: Redefining \colon on input line 410. LaTeX Info: Redefining \colon on input line 410.
\classnum@=\count198 \classnum@=\count199
\DOTSCASE@=\count199 \DOTSCASE@=\count266
LaTeX Info: Redefining \ldots on input line 496. LaTeX Info: Redefining \ldots on input line 496.
LaTeX Info: Redefining \dots on input line 499. LaTeX Info: Redefining \dots on input line 499.
LaTeX Info: Redefining \cdots on input line 620. LaTeX Info: Redefining \cdots on input line 620.
@ -60,20 +60,20 @@ LaTeX Info: Redefining \Bigg on input line 725.
\big@size=\dimen143 \big@size=\dimen143
LaTeX Font Info: Redeclaring font encoding OML on input line 743. LaTeX Font Info: Redeclaring font encoding OML on input line 743.
LaTeX Font Info: Redeclaring font encoding OMS on input line 744. LaTeX Font Info: Redeclaring font encoding OMS on input line 744.
\macc@depth=\count266 \macc@depth=\count267
LaTeX Info: Redefining \bmod on input line 905. LaTeX Info: Redefining \bmod on input line 905.
LaTeX Info: Redefining \pmod on input line 910. LaTeX Info: Redefining \pmod on input line 910.
LaTeX Info: Redefining \smash on input line 940. LaTeX Info: Redefining \smash on input line 940.
LaTeX Info: Redefining \relbar on input line 970. LaTeX Info: Redefining \relbar on input line 970.
LaTeX Info: Redefining \Relbar on input line 971. LaTeX Info: Redefining \Relbar on input line 971.
\c@MaxMatrixCols=\count267 \c@MaxMatrixCols=\count268
\dotsspace@=\muskip16 \dotsspace@=\muskip16
\c@parentequation=\count268 \c@parentequation=\count269
\dspbrk@lvl=\count269 \dspbrk@lvl=\count270
\tag@help=\toks18 \tag@help=\toks18
\row@=\count270 \row@=\count271
\column@=\count271 \column@=\count272
\maxfields@=\count272 \maxfields@=\count273
\andhelp@=\toks19 \andhelp@=\toks19
\eqnshift@=\dimen144 \eqnshift@=\dimen144
\alignsep@=\dimen145 \alignsep@=\dimen145
@ -94,20 +94,20 @@ Package: keyval 2022/05/29 v1.15 key=value parser (DPC)
\KV@toks@=\toks22 \KV@toks@=\toks22
) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/tools\calc.sty ) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/tools\calc.sty
Package: calc 2023/07/08 v4.3 Infix arithmetic (KKT,FJ) Package: calc 2023/07/08 v4.3 Infix arithmetic (KKT,FJ)
\calc@Acount=\count273 \calc@Acount=\count274
\calc@Bcount=\count274 \calc@Bcount=\count275
\calc@Adimen=\dimen150 \calc@Adimen=\dimen150
\calc@Bdimen=\dimen151 \calc@Bdimen=\dimen151
\calc@Askip=\skip53 \calc@Askip=\skip53
\calc@Bskip=\skip54 \calc@Bskip=\skip54
LaTeX Info: Redefining \setlength on input line 80. LaTeX Info: Redefining \setlength on input line 80.
LaTeX Info: Redefining \addtolength on input line 81. LaTeX Info: Redefining \addtolength on input line 81.
\calc@Ccount=\count275 \calc@Ccount=\count276
\calc@Cskip=\skip55 \calc@Cskip=\skip55
) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/mathtools\mhsetup.sty ) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/mathtools\mhsetup.sty
Package: mhsetup 2021/03/18 v1.4 programming setup (MH) Package: mhsetup 2021/03/18 v1.4 programming setup (MH)
) )
\g_MT_multlinerow_int=\count276 \g_MT_multlinerow_int=\count277
\l_MT_multwidth_dim=\dimen152 \l_MT_multwidth_dim=\dimen152
\origjot=\skip56 \origjot=\skip56
\l_MT_shortvdotswithinadjustabove_dim=\dimen153 \l_MT_shortvdotswithinadjustabove_dim=\dimen153
@ -130,8 +130,8 @@ LaTeX Font Info: Redeclaring math symbol \hbar on input line 98.
LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
(Font) U/euf/m/n --> U/euf/b/n on input line 106. (Font) U/euf/m/n --> U/euf/b/n on input line 106.
)) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/l3backend\l3backend-pdftex.def )) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/l3backend\l3backend-pdftex.def
File: l3backend-pdftex.def 2024-01-04 L3 backend support: PDF output (pdfTeX) File: l3backend-pdftex.def 2024-02-20 L3 backend support: PDF output (pdfTeX)
\l__color_backend_stack_int=\count277 \l__color_backend_stack_int=\count278
\l__pdf_internal_box=\box54 \l__pdf_internal_box=\box54
) (main.aux (titlePage.aux)) ) (main.aux (titlePage.aux))
\openout1 = `main.aux'. \openout1 = `main.aux'.
@ -164,16 +164,16 @@ Package graphics Info: Driver file: pdftex.def on input line 107.
File: pdftex.def 2022/09/22 v1.2b Graphics/color driver for pdftex File: pdftex.def 2022/09/22 v1.2b Graphics/color driver for pdftex
(C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/context/base/mkii\supp-pdf.mkii (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/context/base/mkii\supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).] [Loading MPS to PDF converter (version 2006.09.02).]
\scratchcounter=\count278 \scratchcounter=\count279
\scratchdimen=\dimen160 \scratchdimen=\dimen160
\scratchbox=\box55 \scratchbox=\box55
\nofMPsegments=\count279 \nofMPsegments=\count280
\nofMParguments=\count280 \nofMParguments=\count281
\everyMPshowfont=\toks23 \everyMPshowfont=\toks23
\MPscratchCnt=\count281 \MPscratchCnt=\count282
\MPscratchDim=\dimen161 \MPscratchDim=\dimen161
\MPnumerator=\count282 \MPnumerator=\count283
\makeMPintoPDFobject=\count283 \makeMPintoPDFobject=\count284
\everyMPtoPDFconversion=\toks24 \everyMPtoPDFconversion=\toks24
))) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/epstopdf-pkg\epstopdf-base.sty ))) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/epstopdf-pkg\epstopdf-base.sty
Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf
@ -215,24 +215,30 @@ Underfull \hbox (badness 10000) in paragraph at lines 108--111
[] []
[4] [5] [6] [7] [8] (main.aux (titlePage.aux)) [4] [5] [6] [7]
<hw2/gameTree.png, id=40, 511.9125pt x 429.10312pt>
File: hw2/gameTree.png Graphic file (type png)
<use hw2/gameTree.png>
Package pdftex.def Info: hw2/gameTree.png used on input line 271.
(pdftex.def) Requested size: 153.57494pt x 128.73192pt.
[8] [9 <./hw2/gameTree.png>] [10] (main.aux (titlePage.aux))
*********** ***********
LaTeX2e <2023-11-01> patch level 1 LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-01-22> L3 programming layer <2024-02-20>
*********** ***********
) )
Here is how much of TeX's memory you used: Here is how much of TeX's memory you used:
3224 strings out of 474542 3231 strings out of 474436
50311 string characters out of 5744447 50875 string characters out of 5741954
1935978 words of memory out of 5000000 1938190 words of memory out of 5000000
25436 multiletter control sequences out of 15000+600000 25549 multiletter control sequences out of 15000+600000
562573 words of font info for 53 fonts, out of 8000000 for 9000 562573 words of font info for 53 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191 1141 hyphenation exceptions out of 8191
65i,19n,72p,466b,279s stack positions out of 10000i,1000n,20000p,200000b,200000s 65i,19n,72p,505b,279s stack positions out of 10000i,1000n,20000p,200000b,200000s
<C:\Users\uzair\AppData\Local\MiKTeX\fonts/pk/ljfour/jknappen/ec/dpi600\tcrm1000.pk><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmbx10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmbx12.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmex10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmmi10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmmi7.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmr10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmr12.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmr7.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmsy10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmsy7.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmti10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/latxfont/line10.pfb> <C:\Users\uzair\AppData\Local\MiKTeX\fonts/pk/ljfour/jknappen/ec/dpi600\tcrm1000.pk><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmbx10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmbx12.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmex10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmmi10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmmi7.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmr10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmr12.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmr7.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmsy10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmsy7.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/cm/cmti10.pfb><C:/Users/uzair/AppData/Local/Programs/MiKTeX/fonts/type1/public/amsfonts/latxfont/line10.pfb>
Output written on main.pdf (9 pages, 163153 bytes). Output written on main.pdf (11 pages, 219801 bytes).
PDF statistics: PDF statistics:
97 PDF objects out of 1000 (max. 8388607) 106 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000) 0 named destinations out of 1000 (max. 500000)
1 words of extra memory for PDF output out of 10000 (max. 10000000) 6 words of extra memory for PDF output out of 10000 (max. 10000000)

BIN
main.pdf

Binary file not shown.

Binary file not shown.

View File

@ -261,4 +261,64 @@ Now consider UCS running on an arbitrary graph.
\end{itemize} \end{itemize}
\section{Homework 2}
\subsection{Cake}
Alice and Bob are sharing a cake....
\begin{center}
\includegraphics[scale=0.3]{hw2/gameTree.png}
\end{center}
Write down the utility Alice should expect to receive in each of the game states given the following knowlege of player strategies:
\begin{itemize}
\item [a.] Alice and Bob playing adversarially, each trying to maximize the cake they receive.
\begin{enumerate}
\item 1/2
\item 1/2
\item 1/2
\end{enumerate}
\item [b. ] Alice still trying to maximize, Bob now playing collaboratively and helping Alice.
\begin{enumerate}
\item 2/3
\item 1/2
\item 2/3
\end{enumerate}
\item [c. ] Random play.
\begin{enumerate}
\item Node 2 or 3
\item Doesn't matter because of constant utility
\item Node 3
\end{enumerate}
\item [d. ] Alpha Beta pruning
\begin{enumerate}
\item Leaf notes with utility 1/3, 1/3, 1/3, 1/3 on left, and right leaf node with utility 1/6
\end{enumerate}
\item [e. ] Alpha Beta pruning with tree elements swapped.
\begin{enumerate}
\item No nodes are pruned
\end{enumerate}
\end{itemize}
\begin{itemize}
\item [2. ] Logical Formulas
\begin{itemize}
\item [a. ] $(P \land \neg Q) \lor (\neg P \land Q)$
\item [b. ] $(\exists x \text{Course}(x) \land \text{Enrolled}(A, x) \land \text{Enrolled}(B,x))$
\item [c. ] $(\forall x \text{Course}(x) \land \text{Enrolled}(A, x) \rightarrow \text{Enrolled}(B,x))$
\item [d. ] $\forall x \forall y (\text{Enrolled}(x,y) \land \text{Course}(y) \rightarrow \text{Student}(x))$
\item [e. ] $\forall x (\text{Course}(x) \rightarrow \exists y (\text{Student}(y) \land \text{Enrolled}(y,x)))$
\end{itemize}
\end{itemize}
\subsection{Knights and Knaves}
See attached puzzle.py file
\subsection{Odds and Evens}
See attached submission.py file
\end{document} \end{document}