Generate features and find subgroups.
        
            :param filestem: The base name of this experiment.
            :param examples: Classified examples; can be used instead of separate pos / neg files below.
            :param pos: String of positive examples.
            :param neg: String of negative examples.
            :param b: String with background knowledge.
            :param cn2sd: Find subgroups after feature construction?

            :return: a tuple ``(features, weka, rules)``, where:
            - features is a set of prolog clauses of generated features,
            - weka is the propositional form of the input data,
            - rules is a set of generated cn2sd subgroup descriptions; 
              this will be an empty string if cn2sd is set to False.
            :rtype: tuple

def induce(self, b, filestem='default',
               examples=None,
               pos=None,
               neg=None,
               cn2sd=True,
               printOutput=False):
        """
        Generate features and find subgroups.
        
            :param filestem: The base name of this experiment.
            :param examples: Classified examples; can be used instead of separate pos / neg files below.
            :param pos: String of positive examples.
            :param neg: String of negative examples.
            :param b: String with background knowledge.
            :param cn2sd: Find subgroups after feature construction?

            :return: a tuple ``(features, weka, rules)``, where:
            - features is a set of prolog clauses of generated features,
            - weka is the propositional form of the input data,
            - rules is a set of generated cn2sd subgroup descriptions; 
              this will be an empty string if cn2sd is set to False.
            :rtype: tuple
        """
        # Write the inputs
        self.__prepare(filestem, b, examples=examples, pos=pos, neg=neg)

        # Write scripts
        self.__scripts(filestem)

        dumpFile = None
        if not printOutput:
            dumpFile = tempfile.TemporaryFile()

        # Run the script
        logger.info("Running RSD...")
        try:
            for script in RSD.SCRIPTS:
                # Skip subgroup discovery part?
                if script == RSD.SUBGROUPS and not cn2sd:
                    continue
                p = SafePopen(['yap', '-s50000', '-h200000', '-L', script],
                              cwd=self.tmpdir,
                              stdout=dumpFile,
                              stderr=dumpFile).safe_run()
                stdout_str, stderr_str = p.communicate()
                logger.debug(stdout_str)
                logger.debug(stderr_str)
            logger.info("Done.")

            # Return the rules written in the output file.
            features = open('%s/%s' % (self.tmpdir, filestem + '_frs.pl')).read()
            weka = open('%s/%s' % (self.tmpdir, filestem + '.arff')).read()
            rules = open('%s/%s' % (self.tmpdir, filestem + '.rules')).read() if cn2sd else ''

            self.__cleanup()
            return (features, weka, rules)
        except OSError:
            raise RuntimeError("Yap compiler could not be loaded! (see http://www.dcc.fc.up.pt/~vsc/Yap/).")