class_docstr: Logical functions stream generator.
  
  Make a toy dataset with three labels that represent the logical
  functions: `OR`, `XOR`, `AND` (functions of the 2D input).
  
  Data is generated in 'tiles' which contain the complete set of
  logical operations results. The tiles are repeated `n_tiles` times.
  Optionally, the generated data can be shuffled.
  
  Parameters
  ----------
  n_tiles
      Number of tiles to generate.
  shuffle
      If set, generated data will be shuffled.
  seed
      Random seed for reproducibility.
  
  Examples
  --------
  >>> from river.datasets import synth
  
  >>> dataset = synth.Logical(n_tiles=2, shuffle=True, seed=42)
  
  >>> for x, y in dataset.take(5):
  ...     print(x, y)
  {'A': 1, 'B': 1} {'OR': 1, 'XOR': 0, 'AND': 1}
  {'A': 0, 'B': 0} {'OR': 0, 'XOR': 0, 'AND': 0}
  {'A': 1, 'B': 0} {'OR': 1, 'XOR': 1, 'AND': 0}
  {'A': 1, 'B': 1} {'OR': 1, 'XOR': 0, 'AND': 1}
  {'A': 1, 'B': 0} {'OR': 1, 'XOR': 1, 'AND': 0}
code: def __init__(
      self,
      n_tiles: int = 1,
      shuffle: bool = True,
      seed: int | None = None,
  ):
      super().__init__(
          n_features=2,
          n_outputs=3,
          n_samples=4 * n_tiles,
          task=datasets.base.MO_BINARY_CLF,
      )
      self.n_tiles = n_tiles
      self.shuffle = shuffle
      self.seed = seed
      self._rng: np.random.Generator
      self.feature_names = ["A", "B"]
      self.target_names = ["OR", "XOR", "AND"]
  
file_path: river/river/datasets/synth/logical.py
imports: from __future__ import annotations
  import itertools
  import numpy
  from river import datasets
label_desc: Use image node_id 1 to create a new Logical object from inherited base classes: datasets.base with example: obj = Logical(n_tiles, shuffle, seed)