def subset(source, target)
      return [] if source.nil? or target.nil? or source.empty? or target.empty?

      if source == :all or source == "all"
        if target == :all or target == "all"
          return keys
        else
          matches = reverse.subset(target, source)
          return matches.collect{|m| r = m.partition "~"; r.reverse*"" }
        end
      end

      matches = source.uniq.inject([]){|acc,e| 
        if block_given?
          acc.concat(match(e))
        else
          acc.concat(match(e))
        end
      }

      return matches if target == :all or target == "all"

      target_matches = {}

      matches.each{|code| 
        s,sep,t = code.partition "~"
        next if undirected and t > s and source.include? t
        target_matches[t] ||= []
        target_matches[t] << code
      }

      target_matches.values_at(*target.uniq).flatten.compact
    end
def subset(source, target)
      return [] if source.nil? or target.nil? or source.empty? or target.empty?

      if source == :all or source == "all"
        if target == :all or target == "all"
          return keys
        else
          matches = reverse.subset(target, source)
          return matches.collect{|m| r = m.partition "~"; r.reverse*"" }
        end
      end

      matches = source.uniq.inject([]){|acc,e| 
        if block_given?
          acc.concat(match(e))
        else
          acc.concat(match(e))
        end
      }

      return matches if target == :all or target == "all"

      target_matches = {}

      matches.each{|code| 
        s,sep,t = code.partition "~"
        next if undirected and t > s and source.include? t
        target_matches[t] ||= []
        target_matches[t] << code
      }

      target_matches.values_at(*target.uniq).flatten.compact
    end
{{{ Subset