def unit_yuvalOnions(): yuval = scp.scp(epistemicStateType="dl") eatonionSoup = basicLogic.atom("eatOnionSoup") loveEating= basicLogic.atom("loveEating") eatOnions=basicLogic.atom("eatOnions") brushTeeth=basicLogic.atom("brushTeeth") careForHygiene=basicLogic.atom("careForHygiene") dontEatOnions=basicLogic.operator_monotonic_negation(eatOnions) rule1=basicLogic.operator_tritonic_defaultRule(eatonionSoup,[eatOnions],eatOnions) rule2=basicLogic.operator_tritonic_defaultRule(eatonionSoup,[loveEating],loveEating) rule3=basicLogic.operator_tritonic_defaultRule(loveEating,[brushTeeth],brushTeeth) rule4=basicLogic.operator_tritonic_defaultRule(brushTeeth,[careForHygiene],careForHygiene) rule5=basicLogic.operator_tritonic_defaultRule(careForHygiene,[dontEatOnions],dontEatOnions) factEatsOnionSoup = basicLogic.operator_bitonic_implication(basicLogic.TRUE,eatonionSoup) D = [rule1,rule2,rule3,rule4,rule5] W = [factEatsOnionSoup] V = [eatonionSoup, loveEating, eatOnions, brushTeeth, careForHygiene] yuval.addDList(D) yuval.addVList(V) yuval.addWList(W) yuval.addNext(comp_def_eval) print ("<<<<<<<<YUVAL>>>>>>>>>>") print (yuval.evaluate())
def unit_quakersRepublicans(): dick = scp.scp(epistemicStateType="dl") republican = basicLogic.atom('republican') quaker = basicLogic.atom('quaker') pacifist = basicLogic.atom('pacifist') factRepublican = basicLogic.operator_bitonic_implication(basicLogic.TRUE, republican) factQuaker = basicLogic.operator_bitonic_implication(basicLogic.TRUE, quaker) notPacifist = basicLogic.operator_monotonic_negation(pacifist) #republicans are usually not pacifists rule1 = basicLogic.operator_tritonic_defaultRule(republican,[notPacifist],notPacifist) #quakers are usually pacifists rule2 = basicLogic.operator_tritonic_defaultRule(quaker,[pacifist],pacifist) D = [rule1,rule2] W = [factRepublican,factQuaker] V = [republican,quaker,pacifist] dick.addDList(D) dick.addWList(W) dick.addVList(V) dick.addNext(comp_def_eval) print ("<<<<<<<<DICK>>>>>>>>>>") print (dick.evaluate())
def addRuleToScpFromValue(_scp, varName, value=True): if value != None: head = basicLogic.atom(varName, None) body = basicLogic.getGroundAtomFor(value) rule = basicLogic.operator_bitonic_implication(body, head) _scp.addKnowledge(rule) _scp.addVariable(head) return _scp
def createBodyFromRulesThatAffectHead(self, head, body, li_abs): #if basicLogic.isGroundAtom(body): if basicLogic.isGroundAtom(body) or basicLogic.isGroundAtom(head): return basicLogic.operator_bitonic_implication(body, head), None, li_abs newAbnormality = basicLogic.atom('ab{}'.format(len(li_abs) + 1)) negAbnormality = basicLogic.operator_monotonic_negation(newAbnormality) li_abs.append(newAbnormality) newBody = basicLogic.operator_bitonic_and(body, negAbnormality) newRule = basicLogic.operator_bitonic_implication(newBody, head) return newRule, newAbnormality, li_abs
def getVariablesFromThW(thW): v = [] for x in thW: if isinstance(x[0], basicLogic.atom): v.append(copy.deepcopy(x[0])) v[-1].setValue(x[1]) elif isinstance(x[0], basicLogic.operator_monotonic_negation): v.append(copy.deepcopy(x[0].clause)) doubleNeg = basicLogic.operator_monotonic_negation( basicLogic.atom('', x[1])) v[-1].setValue(doubleNeg.evaluate()) return v
def unit_tweetyAndChilly (): #create the two birds as individual scps tweety = scp.scp(epistemicStateType="dl") chilly = scp.scp(epistemicStateType="dl") #variables flies = basicLogic.atom('flies') bird = basicLogic.atom('bird') notflies = basicLogic.operator_monotonic_negation(flies) #the only inference rule rule1 = basicLogic.operator_tritonic_defaultRule(bird,[flies],flies) fact_bird = basicLogic.operator_bitonic_implication(basicLogic.TRUE, bird) factNotFlies = basicLogic.operator_bitonic_implication(basicLogic.TRUE, notflies) #the set of concrete rules W_tweety=[fact_bird] W_chilly=[fact_bird,factNotFlies] #in this case both tweety and chilly share the same inference rules D = [rule1] V = [flies,bird] #create wteety tweety.addDList(D) tweety.addVList(V) tweety.addWList(W_tweety) #create chilly chilly.addDList(D) chilly.addVList(V) chilly.addWList(W_chilly) #add the complex operator for evaluating default rules tweety.addNext(comp_def_eval) chilly.addNext(comp_def_eval) print ("<<<<<<<<TWEETY>>>>>>>>>>") print (tweety.evaluate()) print (chilly.evaluate())
def evaluateEpistemicState(self, epi): #set of conditional rules delta = epi['Delta'] S = epi['S'] V = epi['V'] resolvedDependencies = [] for conditional in delta: consequence = conditional.clause1 precondition = conditional.clause2 if consequence not in resolvedDependencies: lowestk = m_addAB.findLowestK(epi) allDependencies = m_addAB.findAllConditionalDependencyPreconditions( consequence, delta) abBody = None for dep in allDependencies: negateDep = basicLogic.operator_monotonic_negation(dep) if dep != precondition: if abBody == None: abBody = negateDep else: abBody = basicLogic.operator_bitonic_or( abBody, negateDep) if abBody == None: abBody = basicLogic.FALSE abName = 'ab_' + str(lowestk) abAtom = basicLogic.atom(abName, None) ab = basicLogic.operator_bitonic_implication(abAtom, abBody) negABAtom = basicLogic.operator_monotonic_negation(abAtom) newBody = basicLogic.operator_bitonic_and( precondition, negABAtom) newRule = basicLogic.operator_bitonic_implication( consequence, newBody) #add the abnormality and its assignment to the list of rules S.append(newRule) S.append(ab) V.append(abAtom) resolvedDependencies = resolvedDependencies + allDependencies #all conditionals have now been interpreted epi['Delta'] = [] return epi
def evaluate(self): #get the previous epistemic state epi_prev = self.prev.evaluate() #generate an empy epistemic state of the same type as the previous one epi_next = complexOperation.createEmptyNextEpi(epi_prev) #all variables in prevkb will be present in the next one (plus abnormalities) prev_v = epi_prev.getV() epi_next.addVariableList(prev_v) #the list of created abnormalities ABs = [] prev_kb = epi_prev.getKB() for rule in prev_kb: #we do this because there can be 1 or 2 heads/bodies depending on -> or <-> body = self.getBodies(rule) head = self.getHeads(rule) if rule.immutable: epi_next.addKnowledge(rule) else: for h in head: for b in body: #truth values don't need abnormalities if basicLogic.isGroundAtom(b): newRule = basicLogic.operator_bitonic_implication( b, h) epi_next.addKnowledge(newRule) else: #find every clause x, with (x->head) rulesThatAffectHead = self.getRulesThatAffectHead( h, prev_kb) #remove this body from the list of rules that affect head otherRulesThatAffectHead = self.removeRuleFromList( b, rulesThatAffectHead) #create the new abnormality newAb = basicLogic.atom( "ab{}".format(len(ABs) + 1)) ABs.append(newAb) negAb = basicLogic.operator_monotonic_negation( newAb) newBody = basicLogic.operator_bitonic_and(b, negAb) newRule = basicLogic.operator_bitonic_implication( newBody, h) epi_next.addKnowledge(newRule) #create a valuation for the new abnormality abInstHead = newAb abInstBody = self.createNewAbnormalityInstant( otherRulesThatAffectHead) abInstBodyIsGroundValue = basicLogic.isGroundAtom( abInstBody) newAbInstBody = abInstBody if abInstBodyIsGroundValue else basicLogic.operator_monotonic_negation( abInstBody) abInstRule = basicLogic.operator_bitonic_implication( newAbInstBody, abInstHead) epi_next.addKnowledge(abInstRule) #add the new abnormality to the variable list epi_next.addVariable(newAb) return epi_next
# -*- coding: utf-8 -*- """ Created on Mon Jan 20 14:23:02 2020 HEREIN IS AN IMPLEMENTATION OF THE WASON SELECTION TASK USING SCPs @author: Axel """ import basicLogic import scp from scpEvaluator import scp_evaluator import copy import complexOperation import scpError #CARDS THAT CAN BE OBSERVED card_d = basicLogic.atom("D", setValue=False) card_k = basicLogic.atom("K", setValue=False) card_3 = basicLogic.atom("3", setValue=False) card_7 = basicLogic.atom("7", setValue=False) #STARTING RULES, FACTS # the rule d -> 3 which participants are asked to vericy knowledge_dimp3 = basicLogic.operator_bitonic_implication(card_d, card_3) # rules for if each card is seen knowledge_d = basicLogic.operator_bitonic_implication(basicLogic.TRUE, card_d) knowledge_3 = basicLogic.operator_bitonic_implication(basicLogic.TRUE, card_3) knowledge_k = basicLogic.operator_bitonic_implication(basicLogic.TRUE, card_k) knowledge_7 = basicLogic.operator_bitonic_implication(basicLogic.TRUE, card_7) # the extra fact that 7->not(3) #CHANGED pPrime = basicLogic.operator_monotonic_negation(card_3) pPrime = basicLogic.atom("D'", None)
def createAtoms(names, vals): li = [] for i in range(0, len(names)): at = basicLogic.atom(names[i], vals[i]) li.append(at) return li
import scp import complexOperation import scpError import epistemicState print("=================THE SUPPRESSION TASK=========================") print( ">>> 1) If she has an essay to write she will study late in the library (e->l)." ) print( ">>> 2) If the library is open she will study late in the library (o->l).") print(">>> 3) She has an essay to write (True->e).") #STARTING VARIABLES # e: she has an essay to write e = basicLogic.atom('e', setValue=False) # l: she will study late in the library l = basicLogic.atom('l', setValue=False) # o: the library is open o = basicLogic.atom('o', setValue=False) #STARTING RULES, FACTS # if she has an essay to write, she will study late in the library knowledge1 = basicLogic.operator_bitonic_implication(e, l) # she has an essay to write knowledge2 = basicLogic.operator_bitonic_implication(basicLogic.TRUE, e) # if the library is open, she will study late in the library knowledge3 = basicLogic.operator_bitonic_implication(o, l) # the lirary is open knowledge4 = basicLogic.operator_bitonic_implication(basicLogic.TRUE, o)
#print ("evaluation was ", cond.evaluate()) allCondApplicable = False #print ("cond is ",cond) if allCondApplicable: turns.append('Turn Card') #print ("1") else: turns.append('Do Not Turn Card') #print("2") return turns D = basicLogic.atom('D') K = basicLogic.atom('K') three = basicLogic.atom('3') seven = basicLogic.atom('7') Dprime = basicLogic.atom("D'") basePointNoAbd = epistemicState.epistemicState('') #The possible starting states for the SCP delta_contra = ["( 3 | D )", " ( D' | 7 ) "] #delta_nocontra=["( 3 | D )"] #delta1=["( l | e )", "( l | o )"] #S_nocontra = [""] S_contra = ["( ( D ) <- ( ! D' ) )"] #set to 8 to run all abducibles
def polishNotationParser(task, logicType="P"): monotonicOps = { 'Not': basicLogic.operator_monotonic_negation, 'not': basicLogic.operator_monotonic_negation, 'Holds': basicLogic.operator_monotonic_holds, 'Mostly': basicLogic.operator_monotonic_mostly, 'Rarely': basicLogic.operator_monotonic_rarely } bitonicOps = { 'and': basicLogic.operator_bitonic_and, 'or': basicLogic.operator_bitonic_or, 'if': basicLogic.operator_bitonic_implication, 'iff': basicLogic.operator_bitonic_bijection, 'Implies': basicLogic.operator_bitonic_implication } specialMappings = {} ignoredWords = [] #This removes all words in ignoredWords from the list completely #Holds is in this list because its functionality is trivialized by my implementation task = ignoreWords(task, ignoredWords) if len(task) == 1 and not isinstance(task[0], basicLogic.operator): #set true if epistemic state only has kb and no v return [basicLogic.atom(task[0], False)] #@TODO still needs to handle negative initialisations #PROCEDURE # find any case with monotonic operator, base/node # find any case with bitonic operator, base/node, number # find any case with bitonic operator, number, base/node # replace these cases with small node # repeat changeMade = False for i in range(0, len(task)): #Currently empty if task[i] in specialMappings: specialName = task[i] task[i] = specialMappings[specialName]() break #Monotonic Operations elif task[i] in monotonicOps and i < len(task) - 1: if task[i + 1] not in bitonicOps and task[i + 1] not in monotonicOps: clause = task[i + 1] if not isinstance(clause, basicLogic.operator): clause = basicLogic.atom(clause, None) monOp = monotonicOps[task[i]](clause, logicType=logicType) del task[i:i + 2] task.insert(i, monOp) changeMade = True break #Bitonic Operations elif task[i] in bitonicOps and i < len(task) - 2: if task[i + 1] not in bitonicOps and task[i + 2] not in bitonicOps: if task[i + 1] not in monotonicOps and task[i + 2] not in monotonicOps: left = task[i + 1] right = task[i + 2] if not isinstance(left, basicLogic.operator): left = basicLogic.atom(left, None) #x changeMade=True if not isinstance(right, basicLogic.operator): right = basicLogic.atom(right, None) #x changeMade=True bitOp = bitonicOps[task[i]](left, right, logicType=logicType) #does +3 because delete is up to but not including del task[i:i + 3] task.insert(i, bitOp) #x I changed changeMade = True break if changeMade: return polishNotationParser(task) return task
def specialSplit(sp): #find last index def rindex(mylist, myvalue): return len(mylist) - mylist[::-1].index(myvalue) - 1 #must be a literal or a monotonic operator #length 1 can only be an atom or truth value truthValues = { 'T': basicLogic.TRUE, 'u': basicLogic.UNKNOWN, 'F': basicLogic.FALSE } monotonicOps = { '!': basicLogic.operator_monotonic_negation, 'h': basicLogic.operator_monotonic_holds, 'm': basicLogic.operator_monotonic_mostly, 'r': basicLogic.operator_monotonic_rarely } bitonicOps = { '&': basicLogic.operator_bitonic_and, 'or': basicLogic.operator_bitonic_or, '<-': basicLogic.operator_bitonic_implication, '<->': basicLogic.operator_bitonic_bijection, '|': basicLogic.operator_bitonic_conditional } """ newS = [] firstBracket=-1 lastBracket=-1 #if this is a single rule encapsulated by brackets if sp[0]=='(': firstBracket=0 if firstBracket == 0: for s in range( 0, len(sp)): if sp[s]==')': lastBracket=s return specialSplit(sp[firstBracket+1:lastBracket]) else: #find the first operator when there are an equal number of '(' and ')' leftBracketCount = 0 rightBracketCount = 0 if sp[0] in monotonicOps: if sp[1] == '(': return monotonicOps[sp[0]](specialSplit(sp[1:len(sp)])) else: return monotonicOps[sp[0]](specialSplit(sp[1])) for s in range (0, len(sp)): if sp[s]=='(': leftBracketCount=leftBracketCount+1 if sp[s]==')': rightBracketCount=rightBracketCount+1 if leftBracketCount == rightBracketCount: if sp[s] in bitonicOps: clause1 = specialSplit(sp[0:s]) clause2 = specialSplit(sp[s+1:len(sp)]) return bitonicOps[sp[s]](clause1,clause2) """ if len(sp) == 1: if sp[0] in truthValues: return truthValues[sp[0]] return basicLogic.atom(name=sp[0], value=None) if len(sp) == 3: return specialSplit(sp[1]) countleftBracket = 0 counterRightBracket = 0 for i in range(0, len(sp)): if sp[i] == '(': countleftBracket = countleftBracket + 1 if sp[i] == ')': counterRightBracket = counterRightBracket + 1 if countleftBracket == counterRightBracket + 1: if sp[i] in bitonicOps: left = specialSplit(sp[1:i]) right = specialSplit(sp[i + 1:len(sp) - 1]) return bitonicOps[sp[i]](left, right) #if we are here it must be a long clause (monotonicOp, a, b, ..., Z) #is not Atom or (Atom) if sp[1] in monotonicOps: clause = sp[2:len(sp) - 1] return monotonicOps[sp[1]](specialSplit(clause))