Skip to content
Snippets Groups Projects
Commit 8a287269 authored by Valentin Lorentz's avatar Valentin Lorentz
Browse files

Implement intersection simplification.

parent 90c20998
No related branches found
No related tags found
No related merge requests found
import operator
import itertools
from ppp_datamodel.nodes import Resource
......@@ -5,6 +6,13 @@ from ppp_datamodel.nodes.list_operators import *
__all__ = ['simplify']
def partition(pred, list_):
# Partition the items in lists / non-lists
list_ = [x for x in list_ if x]
lists = filter(pred, list_)
not_lists = itertools.filterfalse(pred, list_)
return (lists, not_lists)
def simplify_union(tree):
# Trivial cases
if len(tree.list) == 0:
......@@ -12,24 +20,43 @@ def simplify_union(tree):
elif len(tree.list) == 1:
return tree.list[0]
# Partition the items in lists / non-lists
list_ = [x for x in tree.list if x]
lists = (x.list for x in list_ if isinstance(x, List))
not_lists = [x for x in list_ if not isinstance(x, List)]
(lists, non_lists) = partition(lambda x:isinstance(x, List), tree.list)
# Make union of lists
lists = map(operator.attrgetter('list'), lists)
lists = list(set(itertools.chain(*lists)))
if not_lists: # If there are non-lists (eg. triples)
all_ = not_lists
non_lists = list(non_lists)
if non_lists: # If there are non-lists (eg. triples)
all_ = non_lists
all_.append(List(lists))
return Union(all_)
else: # If there are only lists
return List(lists)
def simplify_intersection(tree):
# Trivial cases
if len(tree.list) == 0:
return tree
elif len(tree.list) == 1:
return tree.list[0]
(lists, non_lists) = partition(lambda x:isinstance(x, List), tree.list)
# Make intersection of lists
lists = list(map(set, map(operator.attrgetter('list'), lists)))
lists = list(lists[0].intersection(*lists[1:]))
non_lists = list(non_lists)
if non_lists: # If there are non-lists (eg. triples)
all_ = non_lists
all_.append(List(lists))
return Intersection(all_)
else: # If there are only lists
return List(lists)
predicates = {
Union: simplify_union
Union: simplify_union,
Intersection: simplify_intersection,
}
def predicate(tree):
......
......@@ -24,3 +24,19 @@ class SimplificationTestCase(unittest.TestCase):
self.assertEqual(t.list[0], T(M(), M(), M()))
self.assertIsInstance(t.list[1], List)
self.assertEqual(set(t.list[1].list), {R('a'), R('b')})
def testIntersectionTrivial(self):
self.assertEqual(simplify(Intersection([])), Intersection([]))
self.assertEqual(simplify(Intersection([List([R('a')])])),
List([R('a')]))
def testIntersectionResourceLists(self):
t = Intersection([List([R('a'), R('b')]), List([R('c'), R('a')])])
t = simplify(t)
self.assertEqual(t, List([R('a')]))
def testIntersectionMixed(self):
t = Intersection([List([R('a'), R('b')]), List([R('c'), R('a')]),
T(M(), M(), M())])
t = simplify(t)
self.assertIsInstance(t, Intersection)
self.assertEqual(t.list[0], T(M(), M(), M()))
self.assertEqual(t.list[1], List([R('a')]))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment