Metadata-Version: 2.1
Name: pystc
Version: 1.0.0
Summary: A simple but extensible Python module for sentences
Home-page: https://github.com/toda-lab/pystc
License: MIT
Keywords: logic,artificial intelligence
Author: Takahisa Toda
Author-email: toda@disc.lab.uec.ac.jp
Requires-Python: >=3.8,<4.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Provides-Extra: docs
Provides-Extra: test
Requires-Dist: Sphinx (>=7.1.2,<8.0.0) ; extra == "docs"
Requires-Dist: pallets-sphinx-themes (>=2.1.1,<3.0.0) ; extra == "docs"
Requires-Dist: pytest (>=8.1.1,<9.0.0) ; extra == "test"
Requires-Dist: sphinx-removed-in (>=0.2.1,<0.3.0) ; extra == "docs"
Requires-Dist: sphinxcontrib-trio (>=1.1.2,<2.0.0) ; extra == "docs"
Project-URL: Repository, https://github.com/toda-lab/pystc
Description-Content-Type: text/x-rst

pystc: A simple but extensible Python module for sentences
==========================================================

Introduction
============
A *sentence* is an atomic sentence or a (compound) sentence.
An *atomic sentence* consists of a *predicate* and *constants* the predicate has
as its arguments.
There is no variable.
The number of arguments of a predicate is called the *arity* of the predicate.
A compound sentence can be obtained by joining sentences with *connectives*.

``pystc`` is a simple but extensible Python module for sentences.
It provides functionality to define sentences as you like 
by adding constants, predicates, and connectives, whether logical or non-logical.
Constants, predicates, and connectives can be introduced by specifying
their names and how they are associated with other well-defined objects or
functions.

Installation
============

.. code:: shell-session

    $ pip install pystc

Usage
=====

Let us first create atomic sentences that can be built from a predicate ``=``
and constants ``T``, ``F``, 

.. code:: python

    from pystc import AtomicSentence

    # Let us add predicate "=" so that the arity for it is 2.
    AtomicSentence.add_predicate("=",2) 
    AtomicSentence.add_constant("T")
    AtomicSentence.add_constant("F")

    # Now, sentences are ready to create.
    s1 = AtomicSentence("=","T","T")
    s2 = AtomicSentence("=","T","F")
    s3 = AtomicSentence("=","F","T")

    assert str(s2) == "=(T,F)"
    assert AtomicSentence.read("=(T,F)") == s2

Let us next construct compound sentences.
A ``Sentence`` in ``pystc`` module is simply a recursive type defined to be:

.. code:: python

    Sentence = Union[str, AtomicSentence, Tuple["Sentence"]]

Although it is loosely defined for simplicity, 
sentences are implicitly expected to fall into one of the following cases:
- An AtomicSentence object, say ``s2``.
- The string representation of an AtomicSentence object, say ``"=(T,F)"``.
- A tuple such that the initial entry is a connective name and the other entries are Sentence objects, say ``("&", s2, ("!", s2))``.

As the connective names ``"&"`` and ``"!"`` appears just above, 
let us introduce these connectives in the following codeblock
and inteprete sentences.

.. code:: python

    from pystc import SentenceConverter

    # Let us set how each symbol should be interpreted.
    SentenceConverter.set_constant_destination("T", True)
    SentenceConverter.set_constant_destination("F", False)
    SentenceConverter.set_predicate_destination("=", lambda li,w: li[0]==li[1])
    SentenceConverter.set_connective_destination("&",lambda li,w: not False in li)
    SentenceConverter.set_connective_destination("|",lambda li,w: True in li)
    SentenceConverter.set_connective_destination("!",lambda li,w: not li[0])

    assert SentenceConverter.convert(s2) == False
    assert SentenceConverter.convert("=(T,F)") == False
    assert SentenceConverter.convert(("&", s2, ("!", s2))) == False
    assert SentenceConverter.convert(("&", "=(T,F)", ("!", s2))) == False

For another example of usage, let us convert sentences into strings in infix
notation.

.. code:: python

    # Clear all class variables
    SentenceConverter.clear()

    SentenceConverter.set_constant_destination("T", "T")
    SentenceConverter.set_constant_destination("F", "F")
    SentenceConverter.set_predicate_destination("=", lambda li,w: f"{li[0]}={li[1]}")
    SentenceConverter.set_connective_destination("&",lambda li,w: "("+" & ".join(li)+")")
    SentenceConverter.set_connective_destination("|",lambda li,w: "("+" | ".join(li)+")")
    SentenceConverter.set_connective_destination("!",lambda li,w: "!"+li[0])

    assert SentenceConverter.convert("=(T,F)") == "T=F"
    assert SentenceConverter.convert(("&", s2, ("!", s2))) == "(T=F & !T=F)"

Let us not forget to clear class variables after everything is finished.

.. code:: python

    SentenceConverter.clear()
    AtomicSentence.clear()


Bugs/Requests/Discussions
=========================

Please report bugs and requests from `GitHub Issues <https://github.com/toda-lab/pystc/issues>`__ , and 
ask questions from `GitHub Discussions <https://github.com/toda-lab/pystc/discussions>`__ .

License
=======

Please see `LICENSE <https://github.com/toda-lab/pystc/blob/main/LICENSE>`__ .

