# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['lstar']

package_data = \
{'': ['*']}

install_requires = \
['attrs>=21.0.0,<22.0.0',
 'dfa>=2.0.0,<3.0.0',
 'funcy>=1.12,<2.0',
 'lazytree>=0.3.2,<0.4.0']

setup_kwargs = {
    'name': 'lstar',
    'version': '1.0.0',
    'description': 'Python implementation of lstar automata learning algorithm.',
    'long_description': '# L*\n\n[![Build Status](https://cloud.drone.io/api/badges/mvcisback/lstar/status.svg)](https://cloud.drone.io/mvcisback/lstar)\n[![codecov](https://codecov.io/gh/mvcisback/lstar/branch/master/graph/badge.svg)](https://codecov.io/gh/mvcisback/lstar)\n[![PyPI version](https://badge.fury.io/py/lstar.svg)](https://badge.fury.io/py/lstar)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nImplementation of the discriminant tree L* algorithm DFA learning algorithm\nprovided in [^1].\n\n\n<!-- markdown-toc start - Don\'t edit this section. Run M-x markdown-toc-generate-toc again -->\n**Table of Contents**\n\n- [Installation](#installation)\n- [Usage](#usage)\n    - [Label Queries](#label-queries)\n    - [Equivalence Queries](#equivalence-queries)\n    - [All together](#all-together)\n- [Learning Moore Machines and DFA-labelers](#learning-moore-machines-and-dfa-labelers)\n- [Testing](#testing)\n- [Footnotes](#footnotes)\n\n<!-- markdown-toc end -->\n\n\n\n# Installation\n\nIf you just need to use `lstar`, you can just run:\n\n`$ pip install lstar`\n\nFor developers, note that this project uses the\n[poetry](https://poetry.eustace.io/) python package/dependency\nmanagement tool. Please familarize yourself with it and then\nrun:\n\n`$ poetry install`\n\n# Usage\n\nThe main entry point for using this library is the `learn_dfa`\nfunction.\n\n```python\nfrom lstar import learn_dfa\n```\n\nThis function requires the arguments:\n```python\ndfa = learn_dfa(\n    inputs= .. ,  #  Inputs over which the target concept is over.\n                    #  Note: Sequence of Hashables.\n\n    label=..,  #  Function answering whether a given word is in the target\n                    #  language.\n                    #\n                    #  Tuple[Alphabet] -> bool\n\n    find_counter_example=..,  #  Function which takes a hypothesis DFA\n                              #  and either returns None or a counter example,\n                              #  i.e., an element misclassified by hypothesis\n                              #  DFA.\n                              #\n                              #  DFA -> Union[Tuple[Alphabet], None]\n\n)\n```\n\nBelow is an example of learning following language over `{0, 1}`:\n\n\n> The number of 1\'s in the word is a multiple of 4.\n\n\n## Label Queries\n\nWe start by defining the label query function. \n\n**Note** that this implementation of `lstar` assumes that this\nfunction is either cheap (`O(1)`-ish) to call or is memoized.\n\n\n```python\nfrom functools import lru_cache\n\n@lru_cache(maxsize=None)  # Memoize member queries \ndef is_mult_4(word):\n    """Want to learn 4 state counter"""\n    return (sum(word) % 4) == 0\n```\n\n## Equivalence Queries\n\nNext you need to define a function which given a candidate `DFA`\nreturns either a counter example that this `DFA` mislabels or `None`.\n\nNote that the `DFA` type used comes from the `dfa` package\n([link](https://github.com/mvcisback/dfa)).\n\n`lstar` provides two functions to make writing counterexample oracles \neasier.\n\n1. `validate_ce`: Takes a counterexample oracle and retries \n   if returned "counterexample" is not actually a counterexample.\n   Useful if using heuristic solver or asking a human.\n\n    ```python\n    from lstar import validate_ce\n\n    @validate_ce(is_mult_4, retry=True)\n    def ask_human(dfa):\n        ...\n    ```\n2. `iterative_deeping_ce`: This function performs an iterative\n   deepening traversal of the candidate dfa and see\'s if it matches\n   the labeler on all tested words.\n\n   ```python\n   from lstar import iterative_deeping_ce\n\n   find_ce = iterative_deeping_ce(is_mult_4, depth=10)\n   ```\n\n\n## All together\n\n```python\ndfa = learn_dfa(\n    inputs={0, 1},  #  Possible inputs.\n    label=is_mult_4,  #  Does this sequence belong in the language.\n    find_counter_example=iterative_deeping_ce(is_mult_4, depth=10)\n)\n\nassert not dfa.label(())\nassert not dfa.label((1,))\nassert not dfa.label((1, 1, ))\nassert dfa.label((1, 1, 1))\nassert dfa.label((1, 1, 0, 1))\n```\n\n# Learning Moore Machines and DFA-labelers\n\nBy default, `learn_dfa` learns as Deterministic Finite Acceptor;\nhowever, by specifying the `outputs` parameter and adjusting the\n`label` function, one can learn a Deterministic Finite Labeler\n(which is isomorphic to a Moore Machine). \n\nFor example, the 4 state counter from before can be modified to output\nthe current count rather than whether or not the word sums to a\nmultiple of 4.\n\n\n```python\ndef sum_mod_4(state):\n    return sum(state) % 4\n\ndfl = learn_dfa(\n    inputs={0, 1},\n    label=sum_mod_4,\n    find_counter_example=ask_human,\n    outputs={0, 1, 2, 3},\n)  # Returns a Deterministic Finite Labeler.\n\nassert dfl.label(()) == 0\nassert dfl.label((1,)) == 1\nassert dfl.label((1, 1, )) == 2\nassert dfl.label((1, 1, 1)) == 3\nassert dfl.label((1, 1, 0, 1)) == 3\nassert dfl.label((1, 1, 1, 1)) == 0\n```\n\nThe deterministic labeler can be interpreted as a moore machine by\nusing the `transduce` method rather than `label`.\n\n```python\nassert dfl.transduce(()) == ()\nassert dfl.transduce((1,)) == (0,)\nassert dfl.transduce((1, 1, )) == (0, 1)\nassert dfl.transduce((1, 1, 1)) == (0, 1, 2)\nassert dfl.transduce((1, 1, 0, 1)) == (0, 1, 2, 2)\nassert dfl.transduce((1, 1, 1, 1, 1)) == (0, 1, 2, 3, 0)\n```\n\n\n# Testing\n\nThis project uses pytest. Simply run\n\n`$ poetry run pytest`\n\nin the root of the repository.\n\n# Similar Libraries\n## Python Based\n    1. https://github.com/steynvl/inferrer : DFA learning\n       library supporting active and passive dfa learning. Active\n       learning is based on L* with an observation table. Also\n       supports learning NFAs.\n\n   1. https://gitlab.lis-lab.fr/dev/scikit-splearn/ : Library for learning\n      weighted automata via the spectral method.\n\n   1. https://pypi.org/project/pylstar/ : Another L* based DFA\n      learning library.\n\n## Java Based\n   1. https://learnlib.de/ : State of the art automata learning\n      toolbox. Supports passive and active learning algorithms for DFAs,\n      Mealy Machines, and Visibly Push Down Automata.\n   1. https://github.com/lorisdanto/symbolicautomata : Library for\n      symbolic automata and symbolic visibly pushdown automata.\n\n# Footnotes\n\n[^1]: Kearns, Michael J., Umesh Virkumar Vazirani, and Umesh Vazirani. An introduction to computational learning theory. MIT press, 1994.\n',
    'author': 'Marcell J. Vazquez-Chanlatte',
    'author_email': 'mvc@linux.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': None,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.9,<4.0',
}


setup(**setup_kwargs)
