Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>DedekindNumber</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>
28 changes: 28 additions & 0 deletions src/solamanDedekind/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
*.pyc

# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Output Files #
################
DedekindLattice/GeneratedDedekindLattices/*
!DedekindLattice/GeneratedDedekindLattices/preserve.txt

# Experimental Files #
######################
**/.noworkflow/**
65 changes: 65 additions & 0 deletions src/solamanDedekind/Dedekind/Algorithms/BottomUp/BottomUp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'''
Created on May 4, 2015

@author: Solaman
'''
from sets import ImmutableSet

def computeAllMIS(setDescription, constraints):
'''
Finds the Minimum Inconsistent Subsets for the given constraints and set Description
using a bottom up approach (where bottom is empty set). We check the powerset of constraints, and rule out possible
MIS based on whether or not a given set is consistent.
NOTE: There are probably far more optimal implementations of such an algorithm. However,
for the sake of comparison, we are only interested in the number of times
'isConsistent' is called and so we refrain from these optimizations.
@param setDescription- A set of rules linking several items together.
Think of this as boolean equation in Conjunctive Normal Form.
@param Constraints- a set of items we would like to include.
Think of this as a value assignment for the previous boolean equation.
'''
setsToCheck = generatePowerset(constraints)
misSet = set()
while len(setsToCheck) > 0:
checkNextSet(setsToCheck, misSet, setDescription)

return misSet


def checkNextSet(setsToCheck, misSet, setDescription):
'''
Takes the smallest set of possible MIS and finds its parents. Then checks if it is consistent.
If it is, then it is an MIS and we should rule out all of its parents.
If it is not, then we rule it out as a possible MIS.
'''
parentSets = set()

chosenSet = setsToCheck.pop()
setsToCheck.add(chosenSet)
for aSet in setsToCheck:
if len(chosenSet) > len(aSet):
chosenSet = aSet

for possibleParent in setsToCheck:
if possibleParent.issuperset(chosenSet) and possibleParent != chosenSet:
parentSets.add(possibleParent)

if setDescription.isConsistent(chosenSet):
misSet.add(chosenSet)
for parentSet in parentSets:
setsToCheck.remove(parentSet)

setsToCheck.remove(chosenSet)



def generatePowerset(theSet):
'''
Generates powerset of a given set.
Original code found at http://stackoverflow.com/questions/18826571/python-powerset-of-a-given-set-with-generators
'''
powerSet = set()
from itertools import chain, combinations
for subset in chain.from_iterable(combinations(theSet, r) for r in range(len(theSet)+1)):
powerSet.add( ImmutableSet(subset))
return powerSet
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
'''
Created on Apr 23, 2015

@author: Solaman
'''
from LogarithmicExtraction import computeSingleMIS
import LogarithmicExtraction
from sets import ImmutableSet

def computeAllMIS(setDescription, constraints):
'''
Taken from 'A Hybrid Diagnosis Approach Combining Black-Box
and White-Box Reasoning'. This attempts to find all Minimal Subset of Constraints
that will be inconsistent for the given Set Description.
@param setDescription- A set of rules linking several items together.
Think of this as boolean equation in Conjunctive Normal Form.
@param Constraints- a set of items we would like to include.
Think of this as an assignment for the previous boolean equation.
'''
misSet= set()
currPath = ImmutableSet()
paths = set()
LogarithmicExtraction.newRun = True
computeAllMISHelper(setDescription, constraints,
misSet, currPath, paths)
return misSet

def computeAllMISHelper(setDescription, constraints, misSet, currPath, paths):
#paths holds all previously visited paths of the hitting set tree
#currPath is the current. If any previous path is a subset of this one
#the we have already computed all MIS that would be found in the current path's subtree.
for path in paths:
if path in currPath:
return

#if the current set of constraints is consistent
#Then there cannot be anymore MIS in its subtree
#so we add the current path to the set of paths enumerated and return.
if not setDescription.isConsistent(constraints):
paths.add(currPath)
return
#In order to avoid redundant MIS computations
#We check the current set of MIS misSet
#If it is possible to find any of the already computed MIS in the current iteration
#(it does not share an element in the currPath) then we just use that MIS
#and continue down the tree
currentMIS = ImmutableSet()
for mis in misSet:
if len(mis.intersection(currPath)) == 0:
currentMIS = mis
break
#If not MIS matches the previous description, we will need to
#compute a new one.
if currentMIS == ImmutableSet():
currentMIS = computeSingleMIS(setDescription, constraints)
misSet.add(currentMIS)

#iterate through the children of the current path
for element in currentMIS:
childPath = currPath.union( set(element))
computeAllMISHelper(setDescription, constraints - ImmutableSet(element), misSet, childPath, paths)

import sets
def computeAllJust(setDescription, artSet, justSet, curpath, allpaths):
'''
Implementation of Hitting Set Tree found directly from EulerX.
A few modifications are made to ensure that it is compatible with this library's
implementation of logarathmic Extraction, otherwise everything else is the same
'''
for path in allpaths:
if path.issubset(curpath):
return
#must be 'not' to be consistent with this library's implementation.
#Without it, it does not compute the MIS properly
#i.e. it does not pass any of the algorithm tests.
if not setDescription.isConsistent(artSet):
allpaths.add(curpath)
return
j = sets.Set()
for s in justSet:
if len(s.intersection(curpath)) == 0:
j = s
if len(j) == 0:
j = computeSingleMIS(setDescription, artSet)
if len(j) != 0:
justSet.add(j)
for a in j:
tmpcur = curpath.union( set(a))
tmpart = artSet - ImmutableSet(a)
computeAllJust(setDescription, tmpart, justSet, tmpcur, allpaths)
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'''
Created on Apr 23, 2015

@author: Solaman
'''
import random
from sets import ImmutableSet

#to avoid checking the empty set as an MIS more than once for
#a given set description, an algorithm can set this to "True" before calling.
#This way the Logarithmic Extraction will know that the check is not excessive
newRun = False

def computeSingleMIS(setDescription, constraints):
'''
Taken from 'A Hybrid Diagnosis Approach Combining Black-Box
and White-Box Reasoning'. This attempts to find the Minimal Subset of Constraints
that will be inconsistent for the given Set Description.
@param setDescription- A set of rules linking several items together.
Think of this as boolean equation in Conjunctive Normal Form.
@param Constraints- a set of items we would like to include.
Think of this as a value assignment for the previous boolean equation.
'''
potentialMIS = computeSingleMISHelper(setDescription, ImmutableSet(), constraints)

#The Euler Implentation does not correctly compute the MIS for a set description
#where everything is always inconsistent (an empty set is inconsistent)
#This makes sense, but this library also considers this set description,
#so we must check the empty configuration here.
global newRun
if newRun == True and len(potentialMIS) == 1 \
and setDescription.isConsistent(ImmutableSet()):
newRun = False
return ImmutableSet()
else:
newRun = False
return potentialMIS

def computeSingleMISHelper(setDescription, currentConstraints, constraintsToAdd):
if len(constraintsToAdd) <= 1:
return constraintsToAdd

constraintsToAddLeft = ImmutableSet(random.sample(constraintsToAdd, len(constraintsToAdd)/2))
constraintsToAddRight = constraintsToAdd - constraintsToAddLeft

#If either subset unioned with the current constraints is inconsistent
#then an MIS exists in the subset of them
if setDescription.isConsistent( currentConstraints.union(constraintsToAddLeft) ):
return computeSingleMISHelper(setDescription, currentConstraints, constraintsToAddLeft)
if setDescription.isConsistent( currentConstraints.union(constraintsToAddRight)):
return computeSingleMISHelper(setDescription, currentConstraints, constraintsToAddRight)

#If both subsets unioned with the current constraints is consistent
#Then an MIS of the current constraints must use elements from both subsets.
#This will find such an MIS
potentialSolutionLeft = computeSingleMISHelper(setDescription,
currentConstraints.union(constraintsToAddRight), constraintsToAddLeft)
potentialSolutionRight = computeSingleMISHelper(setDescription,
currentConstraints.union(potentialSolutionLeft), constraintsToAddRight)
return potentialSolutionLeft.union(potentialSolutionRight)
Empty file.
81 changes: 81 additions & 0 deletions src/solamanDedekind/Dedekind/Algorithms/Random/Random.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'''
Created on May 4, 2015

@author: Solaman
'''
from sets import ImmutableSet
checkedMap = {}

def computeAllMIS(setDescription, constraints):
'''
Finds the Minimum Inconsistent Subsets for the given constraints and set Description
using a randomized approach. We check the powerset of constraints, and rule out possible
MIS based on whether or not a given set is consistent.
NOTE: There are probably far more optimal implementations of such a random algorithm. However,
for the sake of comparison, we are only interested in the number of times
'isConsistent' is called and so we refrain from these optimizations.
@param setDescription- A set of rules linking several items together.
Think of this as boolean equation in Conjunctive Normal Form.
@param Constraints- a set of items we would like to include.
Think of this as a value assignment for the previous boolean equation.
'''
global checkedMap
checkedMap = {}
setsToCheck = generatePowerset(constraints)
misSet = set()
while len(setsToCheck) > 0:
checkRandomSet(setsToCheck, misSet, setDescription)

return misSet


def checkRandomSet(setsToCheck, misSet, setDescription):
'''
Takes a random set from the possible sets available and first finds its parent and children sets.
If it has none, then we know it is an MIS and add it to our solution.
If it has some, then we check if it is consistent and rule out the respective sets.
'''
global checkedMap
import random
chosenSet = random.sample(setsToCheck, 1)[0]
parentSets = set()
childrenSets = set()

for aSet in setsToCheck:
if chosenSet == aSet:
continue
elif aSet.issubset(chosenSet):
childrenSets.add(aSet)
elif aSet.issuperset(chosenSet):
parentSets.add(aSet)

if chosenSet in checkedMap:
if len(parentSets) + len(childrenSets) == 0:
setsToCheck.remove(chosenSet)
misSet.add(chosenSet)
return
else:
if setDescription.isConsistent(chosenSet):
#If consistent, then all parents are consistent and also not MIS
for aSet in parentSets:
setsToCheck.remove(aSet)
else:
#If inconsistent, then all children including this one are inconsistent and also not MIS
for aSet in childrenSets:
setsToCheck.remove(aSet)
setsToCheck.remove(chosenSet)
checkedMap[chosenSet] = 1




def generatePowerset(theSet):
'''
Generates powerset of a given set.
Original code found at http://stackoverflow.com/questions/18826571/python-powerset-of-a-given-set-with-generators
'''
powerSet = set()
from itertools import chain, combinations
for subset in chain.from_iterable(combinations(theSet, r) for r in range(len(theSet)+1)):
powerSet.add( ImmutableSet(subset))
return powerSet
Empty file.
Loading