Completed HW2
This commit is contained in:
parent
9f39068cc2
commit
dfc0f0c7b9
BIN
hw2/gameTree.png
Normal file
BIN
hw2/gameTree.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
BIN
hw2/hw2.pdf
Normal file
BIN
hw2/hw2.pdf
Normal file
Binary file not shown.
BIN
hw2/ints/__pycache__/grader_util.cpython-312.pyc
Normal file
BIN
hw2/ints/__pycache__/grader_util.cpython-312.pyc
Normal file
Binary file not shown.
BIN
hw2/ints/__pycache__/logic.cpython-312.pyc
Normal file
BIN
hw2/ints/__pycache__/logic.cpython-312.pyc
Normal file
Binary file not shown.
BIN
hw2/ints/__pycache__/submission.cpython-312.pyc
Normal file
BIN
hw2/ints/__pycache__/submission.cpython-312.pyc
Normal file
Binary file not shown.
26
hw2/ints/examples.py
Normal file
26
hw2/ints/examples.py
Normal 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
109
hw2/ints/grader.py
Normal 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
448
hw2/ints/grader_util.py
Normal 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
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
BIN
hw2/ints/models/4a-0.pklz
Normal file
Binary file not shown.
BIN
hw2/ints/models/4a-1.pklz
Normal file
BIN
hw2/ints/models/4a-1.pklz
Normal file
Binary file not shown.
BIN
hw2/ints/models/4a-2.pklz
Normal file
BIN
hw2/ints/models/4a-2.pklz
Normal file
Binary file not shown.
BIN
hw2/ints/models/4a-3.pklz
Normal file
BIN
hw2/ints/models/4a-3.pklz
Normal file
Binary file not shown.
BIN
hw2/ints/models/4a-4.pklz
Normal file
BIN
hw2/ints/models/4a-4.pklz
Normal file
Binary file not shown.
BIN
hw2/ints/models/4a-5.pklz
Normal file
BIN
hw2/ints/models/4a-5.pklz
Normal file
Binary file not shown.
BIN
hw2/ints/models/4a-all.pklz
Normal file
BIN
hw2/ints/models/4a-all.pklz
Normal file
Binary file not shown.
42
hw2/ints/submission.py
Normal file
42
hw2/ints/submission.py
Normal 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
|
||||
BIN
hw2/knights/__pycache__/logic.cpython-312.pyc
Normal file
BIN
hw2/knights/__pycache__/logic.cpython-312.pyc
Normal file
Binary file not shown.
260
hw2/knights/logic.py
Normal file
260
hw2/knights/logic.py
Normal 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
82
hw2/knights/puzzle.py
Normal 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()
|
||||
6
main.aux
6
main.aux
@ -10,4 +10,8 @@
|
||||
\@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.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}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
# Fdb version 4
|
||||
["pdflatex"] 1709000449.89094 "c:/Users/uzair/OneDrive/Documents/CSC 665/main.tex" "main.pdf" "main" 1709000450.74539 0
|
||||
"C:/Users/uzair/AppData/Local/MiKTeX/fonts/map/pdftex/pdftex.map" 1707457733 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/miktex/data/le/pdftex/pdflatex.fmt" 1707288883 24210786 eea8c83a2618bf979528f763e32e98c9 ""
|
||||
["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" 1710451113 80909 eab91d9745dd2edfd62a31d53cd5fe15 ""
|
||||
"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" 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/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 ""
|
||||
@ -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/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/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/mhsetup.sty" 1656514886 5582 a43dedf8e5ec418356f1e9dfe5d29fc3 ""
|
||||
"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 ""
|
||||
"main.aux" 1709000450 1087 ba931f15dd3503a818797c381a180181 "pdflatex"
|
||||
"main.tex" 1709000447 12730 ae20bfc5e0f04caa86c900106aea97ed ""
|
||||
"titlePage.aux" 1709000450 456 c979711f53deacf2b09031977e556db8 "pdflatex"
|
||||
"titlePage.tex" 1707288498 394 ccdbd50244b3194dbad72dd1c7995bf0 ""
|
||||
"c:/Users/uzair/OneDrive/Documents/Programming/classes/spring-2024/CSC_665_Homework/main.tex" 1710976753 15294 eefeb5115f03a7d6344da121e4de1ec8 ""
|
||||
"hw2/gameTree.png" 1710872445 51736 b13904e696801b947e455a901505f683 ""
|
||||
"main.aux" 1710976758 1503 e54afcc87f6e15c8bb521b6c8a85270b "pdflatex"
|
||||
"main.tex" 1710976753 15294 eefeb5115f03a7d6344da121e4de1ec8 ""
|
||||
"titlePage.aux" 1710976758 456 c979711f53deacf2b09031977e556db8 "pdflatex"
|
||||
"titlePage.tex" 1710042044 407 ccdbd50244b3194dbad72dd1c7995bf0 ""
|
||||
(generated)
|
||||
"main.aux"
|
||||
"main.log"
|
||||
|
||||
11
main.fls
11
main.fls
@ -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\OneDrive\Documents\CSC 665\main.tex
|
||||
INPUT c:\Users\uzair\OneDrive\Documents\Programming\classes\spring-2024\CSC_665_Homework\main.tex
|
||||
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
|
||||
@ -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\jknappen\ec\tcrm1000.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 .\titlePage.aux
|
||||
INPUT .\titlePage.aux
|
||||
|
||||
98
main.log
98
main.log
@ -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
|
||||
restricted \write18 enabled.
|
||||
file:line:error style messages enabled.
|
||||
%&-line parsing enabled.
|
||||
**"c:/Users/uzair/OneDrive/Documents/CSC 665/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
|
||||
(c:/Users/uzair/OneDrive/Documents/Programming/classes/spring-2024/CSC_665_Homework/main.tex
|
||||
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
|
||||
Document Class: article 2023/05/17 v1.4n Standard LaTeX document class
|
||||
(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)
|
||||
)
|
||||
\c@part=\count187
|
||||
\c@section=\count188
|
||||
\c@subsection=\count189
|
||||
\c@subsubsection=\count190
|
||||
\c@paragraph=\count191
|
||||
\c@subparagraph=\count192
|
||||
\c@figure=\count193
|
||||
\c@table=\count194
|
||||
\c@part=\count188
|
||||
\c@section=\count189
|
||||
\c@subsection=\count190
|
||||
\c@subsubsection=\count191
|
||||
\c@paragraph=\count192
|
||||
\c@subparagraph=\count193
|
||||
\c@figure=\count194
|
||||
\c@table=\count195
|
||||
\abovecaptionskip=\skip48
|
||||
\belowcaptionskip=\skip49
|
||||
\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
|
||||
Package: amsopn 2022/04/08 v2.04 operator names
|
||||
)
|
||||
\inf@bad=\count195
|
||||
\inf@bad=\count196
|
||||
LaTeX Info: Redefining \frac on input line 234.
|
||||
\uproot@=\count196
|
||||
\leftroot@=\count197
|
||||
\uproot@=\count197
|
||||
\leftroot@=\count198
|
||||
LaTeX Info: Redefining \overline on input line 399.
|
||||
LaTeX Info: Redefining \colon on input line 410.
|
||||
\classnum@=\count198
|
||||
\DOTSCASE@=\count199
|
||||
\classnum@=\count199
|
||||
\DOTSCASE@=\count266
|
||||
LaTeX Info: Redefining \ldots on input line 496.
|
||||
LaTeX Info: Redefining \dots on input line 499.
|
||||
LaTeX Info: Redefining \cdots on input line 620.
|
||||
@ -60,20 +60,20 @@ LaTeX Info: Redefining \Bigg on input line 725.
|
||||
\big@size=\dimen143
|
||||
LaTeX Font Info: Redeclaring font encoding OML on input line 743.
|
||||
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 \pmod on input line 910.
|
||||
LaTeX Info: Redefining \smash on input line 940.
|
||||
LaTeX Info: Redefining \relbar on input line 970.
|
||||
LaTeX Info: Redefining \Relbar on input line 971.
|
||||
\c@MaxMatrixCols=\count267
|
||||
\c@MaxMatrixCols=\count268
|
||||
\dotsspace@=\muskip16
|
||||
\c@parentequation=\count268
|
||||
\dspbrk@lvl=\count269
|
||||
\c@parentequation=\count269
|
||||
\dspbrk@lvl=\count270
|
||||
\tag@help=\toks18
|
||||
\row@=\count270
|
||||
\column@=\count271
|
||||
\maxfields@=\count272
|
||||
\row@=\count271
|
||||
\column@=\count272
|
||||
\maxfields@=\count273
|
||||
\andhelp@=\toks19
|
||||
\eqnshift@=\dimen144
|
||||
\alignsep@=\dimen145
|
||||
@ -94,20 +94,20 @@ Package: keyval 2022/05/29 v1.15 key=value parser (DPC)
|
||||
\KV@toks@=\toks22
|
||||
) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/tools\calc.sty
|
||||
Package: calc 2023/07/08 v4.3 Infix arithmetic (KKT,FJ)
|
||||
\calc@Acount=\count273
|
||||
\calc@Bcount=\count274
|
||||
\calc@Acount=\count274
|
||||
\calc@Bcount=\count275
|
||||
\calc@Adimen=\dimen150
|
||||
\calc@Bdimen=\dimen151
|
||||
\calc@Askip=\skip53
|
||||
\calc@Bskip=\skip54
|
||||
LaTeX Info: Redefining \setlength on input line 80.
|
||||
LaTeX Info: Redefining \addtolength on input line 81.
|
||||
\calc@Ccount=\count275
|
||||
\calc@Ccount=\count276
|
||||
\calc@Cskip=\skip55
|
||||
) (C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/latex/mathtools\mhsetup.sty
|
||||
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
|
||||
\origjot=\skip56
|
||||
\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'
|
||||
(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
|
||||
File: l3backend-pdftex.def 2024-01-04 L3 backend support: PDF output (pdfTeX)
|
||||
\l__color_backend_stack_int=\count277
|
||||
File: l3backend-pdftex.def 2024-02-20 L3 backend support: PDF output (pdfTeX)
|
||||
\l__color_backend_stack_int=\count278
|
||||
\l__pdf_internal_box=\box54
|
||||
) (main.aux (titlePage.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
|
||||
(C:\Users\uzair\AppData\Local\Programs\MiKTeX\tex/context/base/mkii\supp-pdf.mkii
|
||||
[Loading MPS to PDF converter (version 2006.09.02).]
|
||||
\scratchcounter=\count278
|
||||
\scratchcounter=\count279
|
||||
\scratchdimen=\dimen160
|
||||
\scratchbox=\box55
|
||||
\nofMPsegments=\count279
|
||||
\nofMParguments=\count280
|
||||
\nofMPsegments=\count280
|
||||
\nofMParguments=\count281
|
||||
\everyMPshowfont=\toks23
|
||||
\MPscratchCnt=\count281
|
||||
\MPscratchCnt=\count282
|
||||
\MPscratchDim=\dimen161
|
||||
\MPnumerator=\count282
|
||||
\makeMPintoPDFobject=\count283
|
||||
\MPnumerator=\count283
|
||||
\makeMPintoPDFobject=\count284
|
||||
\everyMPtoPDFconversion=\toks24
|
||||
))) (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
|
||||
@ -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
|
||||
L3 programming layer <2024-01-22>
|
||||
L3 programming layer <2024-02-20>
|
||||
***********
|
||||
)
|
||||
Here is how much of TeX's memory you used:
|
||||
3224 strings out of 474542
|
||||
50311 string characters out of 5744447
|
||||
1935978 words of memory out of 5000000
|
||||
25436 multiletter control sequences out of 15000+600000
|
||||
3231 strings out of 474436
|
||||
50875 string characters out of 5741954
|
||||
1938190 words of memory out of 5000000
|
||||
25549 multiletter control sequences out of 15000+600000
|
||||
562573 words of font info for 53 fonts, out of 8000000 for 9000
|
||||
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>
|
||||
Output written on main.pdf (9 pages, 163153 bytes).
|
||||
Output written on main.pdf (11 pages, 219801 bytes).
|
||||
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)
|
||||
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.synctex.gz
BIN
main.synctex.gz
Binary file not shown.
60
main.tex
60
main.tex
@ -261,4 +261,64 @@ Now consider UCS running on an arbitrary graph.
|
||||
|
||||
\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}
|
||||
Loading…
Reference in New Issue
Block a user