#################################################################
##  CS 3200 (Fall 2025), Assignment #3                         ##
##  Program File Name: myFDCKBClasses.py                       ##
##       Student Name: Todd Wareham                            ##
##         Login Name: harold                                  ##
##              MUN #: 8008765                                 ##
#################################################################

## Provided classes for Assigment #3.
##
##      *** DO NOT CHANGE THE CODE IN THIS FILE ***
##



## Fact class
## Attributes:
##   str       symbol

class Fact:

   def __init__(self, sym):
      self.symbol = sym

   def __str__(self):
      return str(self.symbol)

   def getSymbol(self):
      return self.symbol


## Definite clause class
## Attributes:
##   str[]     premise
##   str       conclusion

class Clause:

   def __init__(self, prm, con):
      self.premise = prm
      self.conclusion = con

   def __str__(self):
      clsStr = self.premise[0]
      for elem in self.premise[1:]:
         clsStr = clsStr + " + " + elem
      return clsStr + " => " + self.conclusion

   def getPremise(self):
      return self.premise

   def getConclusion(self):
      return self.conclusion


## Definite clause knowledge base class
## Attributes:
##   str[]     symbols
##   fact[]    facts
##   clause[]  clauses

class DCKB:

   def __init__(self, factFilename, clauseFilename):

      f = open(factFilename, "r+")
      numFacts = int(f.readline().strip().split()[1])
      self.facts = []
      for i in range(numFacts):
         self.facts.append(Fact((f.readline().split(":")[1]).strip()))
      f.close()

      f = open(clauseFilename, "r+")
      numClauses = int(f.readline().strip().split()[1])
      self.clauses = []
      for i in range(numClauses):
         s = f.readline().strip().split(":")

         s = s[1].split("=>")
         premiseStr = s[0].strip()
         premise = []
         for elem in premiseStr.split("+"):
            premise.append(elem.strip())
         conclusion = s[1].strip()
         self.clauses.append(Clause(premise, conclusion))
      f.close()

      self.symbols = []
      for f in self.facts:
         s = f.getSymbol()
         if (not(s in self.symbols)):
            self.symbols.append(s)
     
      for c in self.clauses:
         premise = c.getPremise()
         for s in premise:
            if (not(s in self.symbols)):
               self.symbols.append(s)
         conclusion = c.getConclusion()
         if (not(conclusion in self.symbols)):
            self.symbols.append(conclusion)
     

   def getSymbols(self):
      return self.symbols

   def getFacts(self):
      return self.facts

   def getClauses(self):
      return  self.clauses

   def printDCKB(self):
      print("Symbols: ")
      i = 1
      for elem in self.symbols:
         print("   " + str(i) + ": " +  elem)
         i = i + 1
      print("Facts: ")
      i = 1
      for elem in self.facts:
         print("   " + str(i) + ": " +  str(elem))
         i = i + 1
      print("Clauses:")
      i = 1
      for a in self.clauses:
         print("   " + str(i) + ": " + str(a))
         i = i + 1


## Symbol queue class
## Attributes:
##   char[]   queue

class SymbolQueue:

   def __init__(self):
      self.queue = []

   def __str__(self):
      s = ""
      for n in self.queue:
         s = s + str(n) + "\n"
      return s


   def size(self):
      return len(self.queue)


   def isEmpty(self):
      return True if (len(self.queue) == 0) else False


   def push(self, s):
      self.queue.append(s)
         

   def pop(self):
      result = self.queue[0]
      self.queue = self.queue[1:]
      return result



