Skip to main content

L*

Build Status codecov PyPI version License: MIT

Implementation of the discriminant tree L* algorithm DFA learning algorithm provided in 1.

Table of Contents

Installation

If you just need to use lstar, you can just run:

$ pip install lstar

For developers, note that this project uses the poetry python package/dependency management tool. Please familarize yourself with it and then run:

$ poetry install

Usage

The main entry point for using this library is the learn_dfa function.

from lstar import learn_dfa

This function requires the arguments:

dfa = learn_dfa(
    inputs= .. ,  #  Inputs over which the target concept is over.
                    #  Note: Sequence of Hashables.

    label=..,  #  Function answering whether a given word is in the target
                    #  language.
                    #
                    #  Tuple[Alphabet] -> bool

    find_counter_example=..,  #  Function which takes a hypothesis DFA
                              #  and either returns None or a counter example,
                              #  i.e., an element misclassified by hypothesis
                              #  DFA.
                              #
                              #  DFA -> Union[Tuple[Alphabet], None]

)

Below is an example of learning following language over {0, 1}:

The number of 1's in the word is a multiple of 4.

Label Queries

We start by defining the label query function.

Note that this implementation of lstar assumes that this function is either cheap (O(1)-ish) to call or is memoized.

from functools import lru_cache

@lru_cache(maxsize=None)  # Memoize member queries 
def is_mult_4(word):
    """Want to learn 4 state counter"""
    return (sum(word) % 4) == 0

Equivalence Queries

Next you need to define a function which given a candidate DFA returns either a counter example that this DFA mislabels or None.

Note that the DFA type used comes from the dfa package (link).

lstar provides two functions to make writing counterexample oracles easier.

  1. validate_ce: Takes a counterexample oracle and retries if returned "counterexample" is not actually a counterexample. Useful if using heuristic solver or asking a human.

    from lstar import validate_ce
    
    @validate_ce(is_mult_4, retry=True)
    def ask_human(dfa):
        ...
    
  2. iterative_deeping_ce: This function performs an iterative deepening traversal of the candidate dfa and see's if it matches the labeler on all tested words.

    from lstar import iterative_deeping_ce
    
    find_ce = iterative_deeping_ce(is_mult_4, depth=10)
    

All together

dfa = learn_dfa(
    inputs={0, 1},  #  Possible inputs.
    label=is_mult_4,  #  Does this sequence belong in the language.
    find_counter_example=iterative_deeping_ce(is_mult_4, depth=10)
)

assert not dfa.label(())
assert not dfa.label((1,))
assert not dfa.label((1, 1, ))
assert dfa.label((1, 1, 1))
assert dfa.label((1, 1, 0, 1))

Learning Moore Machines and DFA-labelers

By default, learn_dfa learns as Deterministic Finite Acceptor; however, by specifying the outputs parameter and adjusting the label function, one can learn a Deterministic Finite Labeler (which is isomorphic to a Moore Machine).

For example, the 4 state counter from before can be modified to output the current count rather than whether or not the word sums to a multiple of 4.

def sum_mod_4(state):
    return sum(state) % 4

dfl = learn_dfa(
    inputs={0, 1},
    label=sum_mod_4,
    find_counter_example=ask_human,
    outputs={0, 1, 2, 3},
)  # Returns a Deterministic Finite Labeler.

assert dfl.label(()) == 0
assert dfl.label((1,)) == 1
assert dfl.label((1, 1, )) == 2
assert dfl.label((1, 1, 1)) == 3
assert dfl.label((1, 1, 0, 1)) == 3
assert dfl.label((1, 1, 1, 1)) == 0

The deterministic labeler can be interpreted as a moore machine by using the transduce method rather than label.

assert dfl.transduce(()) == ()
assert dfl.transduce((1,)) == (0,)
assert dfl.transduce((1, 1, )) == (0, 1)
assert dfl.transduce((1, 1, 1)) == (0, 1, 2)
assert dfl.transduce((1, 1, 0, 1)) == (0, 1, 2, 2)
assert dfl.transduce((1, 1, 1, 1, 1)) == (0, 1, 2, 3, 0)

Testing

This project uses pytest. Simply run

$ poetry run pytest

in the root of the repository.

Similar Libraries

Python Based

1. https://github.com/steynvl/inferrer : DFA learning
   library supporting active and passive dfa learning. Active
   learning is based on L* with an observation table. Also
   supports learning NFAs.
  1. https://gitlab.lis-lab.fr/dev/scikit-splearn/ : Library for learning weighted automata via the spectral method.

  2. https://pypi.org/project/pylstar/ : Another L* based DFA learning library.

Java Based

  1. https://learnlib.de/ : State of the art automata learning toolbox. Supports passive and active learning algorithms for DFAs, Mealy Machines, and Visibly Push Down Automata.
  2. https://github.com/lorisdanto/symbolicautomata : Library for symbolic automata and symbolic visibly pushdown automata.

Footnotes

  1. Kearns, Michael J., Umesh Virkumar Vazirani, and Umesh Vazirani. An introduction to computational learning theory. MIT press, 1994. ↩

Metadata

Release files for lstar 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lstar 1.0.2
File Size Uploaded Provenance Actions
lstar-1.0.2.tar.gz 6.7 kB Without provenance Details for lstar-1.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for lstar 1.0.2
File Interpreter ABI Platform Actions
lstar-1.0.2-py3-none-any.whl Python 3 none any Details for lstar-1.0.2-py3-none-any.whl

Total release size: 14.9 kB

Release files / lstar-1.0.2.tar.gz

Download URL lstar-1.0.2.tar.gz
Size 6.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4bc3e47f85e1ed2357e09fca3291abf458b731de61c603cda142b3438bd1a0fe
BLAKE2b-256 checksum
How to use checksums
9042b2002728a662b55efb38bee101920197d21949edb96a57a7718df69ee63f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.4.2 CPython/3.10.13 Linux/6.1.62

Release files / lstar-1.0.2-py3-none-any.whl

Download URL lstar-1.0.2-py3-none-any.whl
Size 8.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4b1b328c277404d6d1273638e13bc0e8f72ab1abf7264bbacdff722ccd5d66e7
BLAKE2b-256 checksum
How to use checksums
8a6ca21aa103651038d8017037fa89b08c7f5c2a67727153ca945e9d0f836a21
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.4.2 CPython/3.10.13 Linux/6.1.62

Security for lstar 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page