def resolve_units(self,lit,units,gen,allow_unit_diseqs):
        for lit_idx in list(units): # copy the list in case it changes
            lit2 = lit_rep(self.unit_queue[lit_idx])
            match, subs, eqs = mgu_eq(lit.atom, lit2.atom)
#            print "lit: %s" % lit
            if match and (self.allow_eqs(lit,eqs,True) or (allow_unit_diseqs and len(eqs) == 1 and keep_atom(eqs[0]))):
                new_cl = [Literal(0,eq) for eq in eqs]
                if not self.subsumed_by_used_lit(lit,lit2,new_cl):
                    if verbose():
                        print "units resolve! %s,%s -> %s" % (lit,lit2,new_cl)
                    new_gen = max(gen+1,self.unit_queue_gen[lit_idx])
                    self.add_clause(new_cl,new_gen)
                    if self.unsat:
                        return
    def propagate_lit(self,lit,gen=0,specs = None):
        """
        Perform unit resolution using a literal.

        >>> r = UnitRes(to_clauses("[[a(),b()]]"))
        >>> r.propagate_lit(to_literal('~a()'))
        >>> r.unit_queue
        [b()]
        >>> r.watching
        [{}, {'a': [], 'b': []}]
        >>> r.subsumed
        [0]
        >>> r.clauses
        [[a(), b()]]
        """

#        print self.index
        if self.equational_theory != None and is_ground_equality_lit(lit):
            self.propagate_equality(lit,gen)
            return
#        if lit.atom.relname == '=' and lit.polarity == 0:
#            return
        lits = [lit,Literal(lit.polarity,Atom('=',[lit.atom.args[1],lit.atom.args[0]]))] if lit.atom.relname == '=' else [lit]
        for lit in lits:
            keep = keep_lit(lit)
            indices = list(find_unifying(self.index,Literal(1 - lit.polarity,lit.atom))) # save this in cas index changes
            lit = lit_rep(canonize_literal_unique(lit))
            for index in indices:
                wl = index[1]
    #        print "%s -- %s" % (lit,wl)
                for i,j in list(wl): # copy the list in case we modify it
                    cl = self.clauses[i]
        #            print "cl: %s lit: %s" % (cl,lit)
                    lit2 = lit_rep(cl[j])
                    if lit2.polarity != 1-lit.polarity or lit2.atom.relname != lit.atom.relname:
                        print "!!! %s %s %s %s %s" % (i,j,lit,lit2,cl)
                        exit(1)
                    if is_equality_lit(lit2) and all(isinstance(t,Variable) for t in lit2.atom.args):
                        continue
                    match, subs, eqs = mgu_eq(lit.atom, lit2.atom)
        #            print "lit: %s" % lit
                    if match and self.allow_eqs(lit,eqs,False,cl):
                        if atom_subsume(lit.atom,lit2.atom):
                            self.deindex(i)
                            self.subsumed.append(i)
        #                print "lit: %s" % lit
                        new_cl = [substitute_lit(lit1, subs) for k,lit1 in enumerate(cl) if k != j] + [Literal(0,eq) for eq in eqs]
                        if not new_specialization and not (specs == None):
                            if verbose():
                                print "using specs: %s" % specs
                            new_cl = substitute_constants_clause(new_cl,specs)
                        new_cl = simplify_clause(new_cl)
                        if not is_tautology(new_cl) and not self.subsumed_by_used_lit(lit,cl,new_cl):
                            if verbose():
                                print "%s,%s -> %s" % (lit,cl,new_cl)
                            new_gen = max(gen+1,self.clauses_gen[i])
                            self.add_clause(new_cl,new_gen)
                            if self.unsat:
                                return
                
                if keep:
                    self.resolve_units(lit,index[0],gen,False) # have to unify against units too!
                    if self.unsat:
                        return
            # if we are not keeping this unit as a consequence,
            # resolve it against all of the the units that might match
            # under equality, so that we can infer disequalities
            if keep == False:
                others = [x for x in self.unit_term_index[lit.atom.relname] if self.unit_queue[x].polarity != lit.polarity]
                self.resolve_units(lit,others,gen,True) # 
                if self.unsat:
                    return