blob: 6c8fcbf6fab77b84ee81f68efa14a4c6fe618bbf [file] [log] [blame]
Akrone2744462016-11-15 00:21:43 +01001package Krawfish::Koral::Query::Class;
2use parent 'Krawfish::Koral::Query';
3use Krawfish::Query::Class;
Akronb8aa4f72017-10-22 12:35:04 +02004use Krawfish::Log;
Akrone2744462016-11-15 00:21:43 +01005use strict;
6use warnings;
Akron1fe979b2017-07-25 14:58:47 +02007use Memoize;
8memoize('min_span');
9memoize('max_span');
10
Akrone2744462016-11-15 00:21:43 +010011
Akronb8aa4f72017-10-22 12:35:04 +020012use constant DEBUG => 0;
Akron5b6264f2017-07-19 01:14:01 +020013
Akronb8aa4f72017-10-22 12:35:04 +020014
15# Constructor
Akrone2744462016-11-15 00:21:43 +010016sub new {
17 my $class = shift;
18 bless {
Akron5b6264f2017-07-19 01:14:01 +020019 operands => [shift],
Akrond6d4dc52017-07-25 20:09:35 +020020 number => shift // 1
Akron15fc1972017-07-20 22:53:00 +020021 }, $class;
Akrone2744462016-11-15 00:21:43 +010022};
23
Akrone2744462016-11-15 00:21:43 +010024
25sub type { 'class' };
26
Akron617871f2017-05-27 02:05:31 +020027
Akron5ddc38f2017-07-18 00:16:22 +020028# Remove classes passed as an array references
29sub remove_classes {
30 my ($self, $keep) = @_;
31 unless ($keep) {
32 $keep = [];
33 };
Akron617871f2017-05-27 02:05:31 +020034
Akronb8aa4f72017-10-22 12:35:04 +020035 if (DEBUG) {
36 print_log('kq_q_class', 'Remove classes from ' . $self->to_string);
37 };
38
Akron5b6264f2017-07-19 01:14:01 +020039 $self->{operand}->[0] = $self->{operands}->[0]->remove_classes($keep);
Akron5ddc38f2017-07-18 00:16:22 +020040
Akronb8aa4f72017-10-22 12:35:04 +020041 # Check the keep operand
Akron5ddc38f2017-07-18 00:16:22 +020042 foreach (@$keep) {
Akronb8aa4f72017-10-22 12:35:04 +020043 if ($_ eq $self->number) {
Akron5ddc38f2017-07-18 00:16:22 +020044 return $self;
45 };
46 };
47
Akronb8aa4f72017-10-22 12:35:04 +020048 if (DEBUG) {
49 print_log('kq_q_class', 'Remove own class ' . $self->number);
50 };
51
Akron5ddc38f2017-07-18 00:16:22 +020052 # Return the span only
Akronb8aa4f72017-10-22 12:35:04 +020053 return $self->operand;
Akron5ddc38f2017-07-18 00:16:22 +020054};
55
Akron704ec062017-07-24 15:46:21 +020056# A class always spans its operand span
57sub min_span {
58 $_[0]->operand->min_span;
59};
60
61
62# A class always spans its operand span
63sub max_span {
64 $_[0]->operand->max_span;
65};
66
Akron5ddc38f2017-07-18 00:16:22 +020067
68# Normalize the class query
Akron6d0c8d82017-06-10 14:48:53 +020069sub normalize {
70 my $self = shift;
71
Akron5ddc38f2017-07-18 00:16:22 +020072 # Normalize the span
Akron6d0c8d82017-06-10 14:48:53 +020073 my $span;
Akron5b6264f2017-07-19 01:14:01 +020074 unless ($span = $self->operand->normalize) {
75 $self->copy_info_from($self->operand);
Akron6d0c8d82017-06-10 14:48:53 +020076 return;
77 };
78
Akron852ce872017-06-26 21:29:51 +020079 # Ignore class if span is negative
80 return $span if $span->is_negative;
81
Akron5ddc38f2017-07-18 00:16:22 +020082 # Readd the span
Akron5b6264f2017-07-19 01:14:01 +020083 $self->operand($span);
Akron6d0c8d82017-06-10 14:48:53 +020084 return $self;
85};
86
87
Akron5ddc38f2017-07-18 00:16:22 +020088# Treat the query as if it is root
Akronc5529372017-06-21 15:56:18 +020089sub finalize {
90 my $self = shift;
91
92 my $span;
Akron5b6264f2017-07-19 01:14:01 +020093 unless ($span = $self->operand->finalize) {
94 $self->copy_info_from($self->operand);
Akronc5529372017-06-21 15:56:18 +020095 return;
96 };
97
Akron5b6264f2017-07-19 01:14:01 +020098 $self->operand($span);
Akronc5529372017-06-21 15:56:18 +020099 return $self;
100};
101
102
Akron48fabe52017-08-07 16:48:12 +0200103# Optimize on segment
Akron6d0c8d82017-06-10 14:48:53 +0200104sub optimize {
Akron48fabe52017-08-07 16:48:12 +0200105 my ($self, $segment) = @_;
Akron6d0c8d82017-06-10 14:48:53 +0200106
Akron48fabe52017-08-07 16:48:12 +0200107 my $span = $self->operand->optimize($segment);
Akron6d0c8d82017-06-10 14:48:53 +0200108
109 # Span has no match
Akronfaf76852017-07-19 17:37:07 +0200110 if ($span->max_freq == 0) {
Akron5a5595b2017-09-10 13:00:57 +0200111 return $self->builder->nowhere;
Akron6d0c8d82017-06-10 14:48:53 +0200112 };
113
114 return Krawfish::Query::Class->new(
115 $span,
116 $self->number
117 );
118};
119
120
Akron965f5d92017-01-20 18:38:08 +0100121# Iterate over all subqueries and replace them
122# if necessary
Akron6ff7b482017-02-09 01:29:29 +0100123#sub replace_subqueries {
124# my ($self, $cb) = @_;
125#
126# # Check if the subspan should be replaced
Akron5b6264f2017-07-19 01:14:01 +0200127# if (my $replace = $cb->($self->operand)) {
Akron6ff7b482017-02-09 01:29:29 +0100128#
129# # Replace
130# $self->{span} = $replace;
131# };
132#};
Akron965f5d92017-01-20 18:38:08 +0100133
134
Akron965f5d92017-01-20 18:38:08 +0100135
Akrone2744462016-11-15 00:21:43 +0100136sub to_string {
137 my $self = shift;
138 my $str = '{';
139 $str .= $self->number . ':' if $self->number;
Akron5b6264f2017-07-19 01:14:01 +0200140 return $str . $self->operand->to_string . '}';
Akrone2744462016-11-15 00:21:43 +0100141};
142
Akron965f5d92017-01-20 18:38:08 +0100143
Akrone2744462016-11-15 00:21:43 +0100144sub number {
145 $_[0]->{number};
146};
147
Akron965f5d92017-01-20 18:38:08 +0100148
Akron655a10a2017-09-11 14:13:18 +0200149sub is_anywhere {
150 $_[0]->operand->is_anywhere;
Akrone2744462016-11-15 00:21:43 +0100151};
152
Akron965f5d92017-01-20 18:38:08 +0100153
Akrone2744462016-11-15 00:21:43 +0100154sub is_optional {
Akron5b6264f2017-07-19 01:14:01 +0200155 $_[0]->operand->is_optional;
Akrone2744462016-11-15 00:21:43 +0100156};
157
Akron965f5d92017-01-20 18:38:08 +0100158
Akrone2744462016-11-15 00:21:43 +0100159sub is_null {
Akron5b6264f2017-07-19 01:14:01 +0200160 $_[0]->operand->is_null;
Akrone2744462016-11-15 00:21:43 +0100161};
162
Akron965f5d92017-01-20 18:38:08 +0100163
Akrone2744462016-11-15 00:21:43 +0100164sub is_negative {
Akron5ddc38f2017-07-18 00:16:22 +0200165 my $self = shift;
Akron5b6264f2017-07-19 01:14:01 +0200166 my $span = $self->operand;
Akron5ddc38f2017-07-18 00:16:22 +0200167 if (@_) {
168 $span->is_negative(@_);
169 return $self;
170 };
171 return $span->is_negative;
Akrone2744462016-11-15 00:21:43 +0100172};
173
Akron965f5d92017-01-20 18:38:08 +0100174
Akrone2744462016-11-15 00:21:43 +0100175sub is_extended {
Akron5b6264f2017-07-19 01:14:01 +0200176 $_[0]->operand->is_extended;
Akrone2744462016-11-15 00:21:43 +0100177};
178
Akron965f5d92017-01-20 18:38:08 +0100179
Akrone2744462016-11-15 00:21:43 +0100180sub is_extended_right {
Akron5b6264f2017-07-19 01:14:01 +0200181 $_[0]->operand->is_extended_right;
Akrone2744462016-11-15 00:21:43 +0100182};
183
Akron965f5d92017-01-20 18:38:08 +0100184
Akrone2744462016-11-15 00:21:43 +0100185sub is_extended_left {
Akron5b6264f2017-07-19 01:14:01 +0200186 $_[0]->operand->is_extended_left;
Akrone2744462016-11-15 00:21:43 +0100187};
188
Akron965f5d92017-01-20 18:38:08 +0100189
Akron1b09c5b2016-11-20 15:59:34 +0100190sub maybe_unsorded {
Akron5b6264f2017-07-19 01:14:01 +0200191 $_[0]->operand->maybe_unsorted;
Akron1b09c5b2016-11-20 15:59:34 +0100192};
193
Akron965f5d92017-01-20 18:38:08 +0100194
Akrone2744462016-11-15 00:21:43 +0100195sub is_classed { 1 };
196
Akron944091b2016-11-24 16:40:58 +0100197
198sub from_koral {
199 my ($class, $kq) = @_;
200 my $importer = $class->importer;
201
202 my $nr = $kq->{'classOut'} or warn 'No class defined';
203
204 # Import operand
205 my $op = $importer->all($kq->{operands}->[0]);
206
207 return $class->new($op, $nr);
208};
209
Akron965f5d92017-01-20 18:38:08 +0100210
Akronb8aa4f72017-10-22 12:35:04 +0200211# Serialize to KoralQuery
212sub to_koral_fragment {
213 my $self = shift;
214 return {
215 '@type' => 'koral:group',
216 'operation' => 'operation:class',
217 'classOut' => $self->number,
218 'operands' => [
219 $self->operand->to_koral_fragment
220 ]
221 };
222};
223
224
Akrone2744462016-11-15 00:21:43 +01002251;