<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def search(self, *conditions):
 """ Given a set of conditions, return all values that satisfy the conditions for a given set of variables. For example, suppose I wanted to find all of my friends who live in Kansas: .. code-block:: python X = graph.v.X results = graph.search( {'s': 'charlie', 'p': 'friends', 'o': X}, {'s': X, 'p': 'lives', 'o': 'Kansas'}) The return value consists of a dictionary keyed by variable, whose values are ``set`` objects containing the values that satisfy the query clauses, e.g.: .. code-block:: python print results # Result has one key, for our "X" variable. The value is the set # of my friends that live in Kansas. # {'X': {'huey', 'nuggie'}} # We can assume the following triples exist: # ('charlie', 'friends', 'huey') # ('charlie', 'friends', 'nuggie') # ('huey', 'lives', 'Kansas') # ('nuggie', 'lives', 'Kansas') """

        results = {}

        for condition in conditions:
            if isinstance(condition, tuple):
                query = dict(zip('spo', condition))
            else:
                query = condition.copy()
            materialized = {}
            targets = []

            for part in ('s', 'p', 'o'):
                if isinstance(query[part], Variable):
                    variable = query.pop(part)
                    materialized[part] = set()
                    targets.append((variable, part))

            # Potentially rather than popping all the variables, we could use
            # the result values from a previous condition and do O(results)
            # loops looking for a single variable.
            for result in self.query(**query):
                ok = True
                for var, part in targets:
                    if var in results and result[part] not in results[var]:
                        ok = False
                        break

                if ok:
                    for var, part in targets:
                        materialized[part].add(result[part])

            for var, part in targets:
                if var in results:
                    results[var] &= materialized[part]
                else:
                    results[var] = materialized[part]

        return dict((var.name, vals) for (var, vals) in results.items())