Improve composition on queries

Change-Id: I3c9bbab37143268eafbadcb1ba1bff85a3842788
diff --git a/lib/Krawfish/Koral/Report.pm b/lib/Krawfish/Koral/Report.pm
index 6d47124..aaca5be 100644
--- a/lib/Krawfish/Koral/Report.pm
+++ b/lib/Krawfish/Koral/Report.pm
@@ -3,9 +3,9 @@
 use strict;
 use warnings;
 use Krawfish::Log;
+requires qw/error warning message has_error has_warning has_message/;
 
-# TODO:
-#   Probably rename to Krawfish::Koral::Report
+# Report on errors, warnings an anything else
 
 use constant DEBUG => 0;
 
diff --git a/lib/Krawfish/Koral/Result/Group/Fields.pm b/lib/Krawfish/Koral/Result/Group/Fields.pm
index 5840c02..193a7d6 100644
--- a/lib/Krawfish/Koral/Result/Group/Fields.pm
+++ b/lib/Krawfish/Koral/Result/Group/Fields.pm
@@ -6,6 +6,11 @@
 
 use constant DEBUG => 0;
 
+# Group on a sequence of field values
+
+# TODO:
+#   Support corpus classes
+
 # TODO:
 #   In addition to the group name
 #   create a signature that is universal for each group
diff --git a/lib/Krawfish/Query.pm b/lib/Krawfish/Query.pm
index 4ab0ae6..a7d8fb4 100644
--- a/lib/Krawfish/Query.pm
+++ b/lib/Krawfish/Query.pm
@@ -1,4 +1,16 @@
 package Krawfish::Query;
+use Role::Tiny;
+requires qw/current
+            next
+            next_doc
+            skip_doc
+            skip_pos
+            same_doc
+            clone
+            max_freq
+            filter_by
+            requires_filter
+            to_string/;
 use Krawfish::Log;
 use Krawfish::Posting::Span;
 use Scalar::Util qw/blessed refaddr/;
@@ -14,7 +26,7 @@
 
 use constant DEBUG => 0;
 
-# Current span object
+# Current span posting object
 sub current {
   my $self = shift;
   return unless defined $self->{doc_id};
@@ -30,14 +42,6 @@
 };
 
 
-# Move to next posting
-# Overwrite
-# Returns true if nexting works
-sub next {
-  ...
-};
-
-
 # This is only relevant for term posting lists
 sub next_doc {
   my $self = shift;
@@ -164,36 +168,7 @@
 };
 
 
-# Get maximum possible frequency of the query
-sub max_freq {
-  warn 'Not implemented for this query: ' . blessed $_[0];
-};
-
-
-# Filter nothing
-sub filter_by {
-  warn 'Not implemented by default';
-};
-
-
-# Return a true value if a query requires a filter,
-# otherwise returns a false value.
-# This needs to be overwritten
-sub requires_filter {
-  warn 'Not implemented in ' . $_[0] . ' from ' . join(', ', caller);
-  ...
-};
-
-
-# Stringification
-# Overwrite
-sub to_string {
-  ...
-};
-
-
 # Get current match
-# Override
 sub current_match {
   return undef;
 };
@@ -202,7 +177,7 @@
 
 # Lose all information about the query
 sub close {
-
+  ...
 };
 
 
diff --git a/lib/Krawfish/Query/Base/Dual.pm b/lib/Krawfish/Query/Base/Dual.pm
index 6ddf3f2..49e94ce 100644
--- a/lib/Krawfish/Query/Base/Dual.pm
+++ b/lib/Krawfish/Query/Base/Dual.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Base::Dual;
-use parent 'Exporter', 'Krawfish::Query';
+use Role::Tiny;
+use parent 'Exporter';
 use strict;
 use warnings;
 use Krawfish::Log;
diff --git a/lib/Krawfish/Query/Base/Sorted.pm b/lib/Krawfish/Query/Base/Sorted.pm
index 81579db..6d06480 100644
--- a/lib/Krawfish/Query/Base/Sorted.pm
+++ b/lib/Krawfish/Query/Base/Sorted.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Base::Sorted;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Log;
 use strict;
 use warnings;
@@ -44,6 +45,27 @@
 };
 
 
+sub max_freq {
+  $_->{span}->max_freq;
+};
+
+
+sub filter_by {
+  my $self = shift;
+  $self->{span}->filter_by(@_);
+};
+
+
+sub requires_filter {
+  shift->{span}->requires_filter;
+};
+
+sub to_string {
+  my $self = shift;
+  return 'sorted(' . $self->{span}->to_string . ')';
+};
+
+
 # Move to next sorted posting
 sub next {
   my $self = shift;
diff --git a/lib/Krawfish/Query/Cache.pm b/lib/Krawfish/Query/Cache.pm
index 4ce991e..d2b5b78 100644
--- a/lib/Krawfish/Query/Cache.pm
+++ b/lib/Krawfish/Query/Cache.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Cache;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Index::Stream;
 use Krawfish::Cache;
 use strict;
diff --git a/lib/Krawfish/Query/Class.pm b/lib/Krawfish/Query/Class.pm
index b03416e..89e8475 100644
--- a/lib/Krawfish/Query/Class.pm
+++ b/lib/Krawfish/Query/Class.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Class;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Log;
 use strict;
 use warnings;
diff --git a/lib/Krawfish/Query/Constraints.pm b/lib/Krawfish/Query/Constraints.pm
index 1c4e9b6..3f4902d 100644
--- a/lib/Krawfish/Query/Constraints.pm
+++ b/lib/Krawfish/Query/Constraints.pm
@@ -1,5 +1,7 @@
 package Krawfish::Query::Constraints;
-use parent 'Krawfish::Query::Base::Dual';
+use Role::Tiny::With;
+with 'Krawfish::Query::Base::Dual';
+with 'Krawfish::Query';
 use Krawfish::Util::Buffer;
 use List::Util qw/min/;
 use Krawfish::Log;
diff --git a/lib/Krawfish/Query/Exclusion.pm b/lib/Krawfish/Query/Exclusion.pm
index 344a2db..9a614c0 100644
--- a/lib/Krawfish/Query/Exclusion.pm
+++ b/lib/Krawfish/Query/Exclusion.pm
@@ -1,5 +1,7 @@
 package Krawfish::Query::Exclusion;
-use parent 'Krawfish::Query::Base::Dual';
+use Role::Tiny::With;
+with 'Krawfish::Query::Base::Dual';
+with 'Krawfish::Query';
 use Krawfish::Query::Base::Dual;
 use Krawfish::Query::Constraint::Position; # Export constants and @next_a and @next_b
 use Krawfish::Util::Bits; # exports bitstring
diff --git a/lib/Krawfish/Query/Extension.pm b/lib/Krawfish/Query/Extension.pm
index 73210b0..f0ef5af 100644
--- a/lib/Krawfish/Query/Extension.pm
+++ b/lib/Krawfish/Query/Extension.pm
@@ -1,6 +1,7 @@
 package Krawfish::Query::Extension;
-use parent 'Krawfish::Query::Base::Dual';
-use Krawfish::Query::Base::Dual;
+use Role::Tiny::With;
+with 'Krawfish::Query::Base::Dual';
+with 'Krawfish::Query';
 use strict;
 use warnings;
 
diff --git a/lib/Krawfish/Query/Filter.pm b/lib/Krawfish/Query/Filter.pm
index ff05316..344e60d 100644
--- a/lib/Krawfish/Query/Filter.pm
+++ b/lib/Krawfish/Query/Filter.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Filter;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Log;
 use strict;
 use warnings;
diff --git a/lib/Krawfish/Query/InCorpus.pm b/lib/Krawfish/Query/InCorpus.pm
index dddfe0c..0ac6327 100644
--- a/lib/Krawfish/Query/InCorpus.pm
+++ b/lib/Krawfish/Query/InCorpus.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::InCorpus;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Util::Bits;
 use Krawfish::Log;
 use strict;
diff --git a/lib/Krawfish/Query/Length.pm b/lib/Krawfish/Query/Length.pm
index 6976aa7..44680c8 100644
--- a/lib/Krawfish/Query/Length.pm
+++ b/lib/Krawfish/Query/Length.pm
@@ -1,4 +1,6 @@
 package Krawfish::Query::Length;
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Log;
 use strict;
 use warnings;
diff --git a/lib/Krawfish/Query/Match.pm b/lib/Krawfish/Query/Match.pm
index 22f0671..cbbfa97 100644
--- a/lib/Krawfish/Query/Match.pm
+++ b/lib/Krawfish/Query/Match.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Match;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Log;
 use strict;
 use warnings;
diff --git a/lib/Krawfish/Query/Nowhere.pm b/lib/Krawfish/Query/Nowhere.pm
index 799571e..4c3bf82 100644
--- a/lib/Krawfish/Query/Nowhere.pm
+++ b/lib/Krawfish/Query/Nowhere.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Nowhere;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use strict;
 use warnings;
 
diff --git a/lib/Krawfish/Query/Or.pm b/lib/Krawfish/Query/Or.pm
index 2030627..c0387f8 100644
--- a/lib/Krawfish/Query/Or.pm
+++ b/lib/Krawfish/Query/Or.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Or;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Log;
 use strict;
 use warnings;
diff --git a/lib/Krawfish/Query/Reference.pm b/lib/Krawfish/Query/Reference.pm
index af062f6..2ec1e2a 100644
--- a/lib/Krawfish/Query/Reference.pm
+++ b/lib/Krawfish/Query/Reference.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Reference;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Log;
 use strict;
 use warnings;
diff --git a/lib/Krawfish/Query/Repetition.pm b/lib/Krawfish/Query/Repetition.pm
index b2ee5e2..a5f298e 100644
--- a/lib/Krawfish/Query/Repetition.pm
+++ b/lib/Krawfish/Query/Repetition.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Repetition;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Util::Buffer;
 use Krawfish::Log;
 use Krawfish::Posting;
diff --git a/lib/Krawfish/Query/TermID.pm b/lib/Krawfish/Query/TermID.pm
index d75d588..f879da1 100644
--- a/lib/Krawfish/Query/TermID.pm
+++ b/lib/Krawfish/Query/TermID.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::TermID;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Posting::Span;
 use Krawfish::Query::Filter;
 use Krawfish::Log;
diff --git a/lib/Krawfish/Query/Unique.pm b/lib/Krawfish/Query/Unique.pm
index 5a1ae96..8dedb9a 100644
--- a/lib/Krawfish/Query/Unique.pm
+++ b/lib/Krawfish/Query/Unique.pm
@@ -1,5 +1,6 @@
 package Krawfish::Query::Unique;
-use parent 'Krawfish::Query';
+use Role::Tiny::With;
+with 'Krawfish::Query';
 use Krawfish::Log;
 use strict;
 use warnings;