+ my $c = 1 - count $r;
+ return $r, $c ? { 'list' => $c } : undef
+}
+
+sub pp_grepwhile {
+ my ($self, $op) = @_;
+
+ $op = $op->first;
+ return $self->inspect($op) if name($op) ne 'grepstart';
+ $op = $op->first->sibling;
+
+ my ($r2, $l2) = $self->inspect($op->sibling);
+ return $r2, $l2 if defined $r2 and zero $l2;
+ my $c2 = count $l2; # First one to happen
+
+ my ($r1, $l1) = $self->inspect($op);
+ return (add $r2, scale $c2, $r1), undef if defined $r1 and zero $l1
+ and not zero $l2;
+ my $c1 = count $l1;
+
+ $l2 = { $l2 => 1 } unless ref $l2;
+ my $r = add $r2,
+ scale $c2,
+ add map { scale $l2->{$_}, cumulate $r1, $_, $c1 } keys %$l2;
+ my $c = 1 - count $r;
+ return $r, $c ? { ((zero $l2) ? 0 : 'list') => $c } : undef;
+}
+
+sub pp_mapwhile {
+ my ($self, $op) = @_;
+
+ $op = $op->first;
+ return $self->inspect($op) if name($op) ne 'mapstart';
+ $op = $op->first->sibling;
+
+ my ($r2, $l2) = $self->inspect($op->sibling);
+ return $r2, $l2 if defined $r2 and zero $l2;
+ my $c2 = count $l2; # First one to happen
+
+ my ($r1, $l1) = $self->inspect($op);
+ return (add $r2, scale $c2, $r1), undef if defined $r1 and zero $l1
+ and not zero $l2;
+ my $c1 = count $l1;
+
+ $l2 = { $l2 => 1 } unless ref $l2;
+ my $r = add $r2,
+ scale $c2,
+ add map { scale $l2->{$_}, cumulate $r1, $_, $c1 } keys %$l2;
+ my $c = 1 - count $r;
+ my $l = scale $c, normalize add map { power $l1, $_, $l2->{$_} } keys %$l2;
+ return $r, $l;