Initial Commit with Script
This commit is contained in:
commit
199fa45cf5
39
README.md
Normal file
39
README.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Logic formula checker
|
||||||
|
Script for checking is formula is correct
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
You can run this script without downloading any other libraries.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
There are several ways of usage.
|
||||||
|
+ You can use is as a library in your project:
|
||||||
|
```
|
||||||
|
from logic_formula_checker import is_formula_correct
|
||||||
|
```
|
||||||
|
+ With run.py for interactive console
|
||||||
|
+ From bash
|
||||||
|
```
|
||||||
|
$ python -m logic_formula_checker -f (a∧b)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
Some tests is written in tests.py file. They check if formula single tests work properly.
|
||||||
|
|
||||||
|
|
||||||
|
## Script logic explaination
|
||||||
|
It takes two test of formula for checking formula's correctness.
|
||||||
|
Firstly check if all brackets are properly opened and closed.
|
||||||
|
```
|
||||||
|
( { } ) - Good
|
||||||
|
( { ) } - Wrong
|
||||||
|
( { } - Wrong
|
||||||
|
```
|
||||||
|
Next script checks if signs are rightly put. Brackets are bypassed. Steps:
|
||||||
|
1. Read sign, check what kind it is (Types are in logic_formula_checker/types.py).
|
||||||
|
2. Check if it is in expected_sign list.
|
||||||
|
3. Update expected_sign list base on current sign
|
||||||
|
```
|
||||||
|
a ^ ¬ b // take a, write to expected_sign conjuction symbols and negation symbols
|
||||||
|
^ ¬ b // take ^, check is it in expected_sign, update expected_sign with asci lowercase sings (formula variables) and negation signs
|
||||||
|
|
||||||
|
```
|
3
logic_formula_checker/__init__.py
Normal file
3
logic_formula_checker/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from .__main__ import *
|
||||||
|
from .utils import *
|
||||||
|
from .types import *
|
28
logic_formula_checker/__main__.py
Normal file
28
logic_formula_checker/__main__.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from .utils import *
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = ArgumentParser(description="Check correctness of logic formula")
|
||||||
|
parser.add_argument('-f', '--formula', dest=formula, metavar='FORMULA')
|
||||||
|
parser.add_argument('-fl', '--formula-list', dest=list_formula, metavar='[FORMULA, FORMULA]')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
args = parse_args()
|
||||||
|
if args.list_formula:
|
||||||
|
list_formula = json.loads(args.list_formula)
|
||||||
|
if not isinstance(list_formula, list):
|
||||||
|
print('Type of --formula-list is not a list')
|
||||||
|
else:
|
||||||
|
for formula in list_formula:
|
||||||
|
print(
|
||||||
|
"{}: {}".format(formula, is_formula_correct(formula))
|
||||||
|
)
|
||||||
|
elif args.formula:
|
||||||
|
print(
|
||||||
|
"{}: {}".format(args.formula, is_formula_correct(args.formula))
|
||||||
|
)
|
27
logic_formula_checker/types.py
Normal file
27
logic_formula_checker/types.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import string
|
||||||
|
|
||||||
|
|
||||||
|
class SentenceVariable(object):
|
||||||
|
symbols = string.ascii_lowercase
|
||||||
|
|
||||||
|
|
||||||
|
class SupportSign(object):
|
||||||
|
symbols_open = ['[', '{', '(']
|
||||||
|
symbols_close = [']', '}', ')']
|
||||||
|
symbols = symbols_open + symbols_close
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_closed_symbol(cls, open_symbol):
|
||||||
|
return cls.symbols_close[cls.symbols_open.index(open_symbol)]
|
||||||
|
|
||||||
|
|
||||||
|
class SentenceConjunction(object):
|
||||||
|
symbols_conjunction = ['.', '*', '&', '∧', 'AND']
|
||||||
|
symbols_alternative = ['+', '∧', 'A', 'OR']
|
||||||
|
symbols_implication = ['⇒', '→', '⊃']
|
||||||
|
symbols_equivalence = ['⇔', '≡', '↔']
|
||||||
|
symbols = symbols_conjunction + symbols_alternative + symbols_implication + symbols_implication
|
||||||
|
|
||||||
|
|
||||||
|
class Negation(object):
|
||||||
|
symbols = ['!', '¬', '˜']
|
45
logic_formula_checker/utils.py
Normal file
45
logic_formula_checker/utils.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
from .types import SupportSign, SentenceConjunction, SentenceVariable, Negation
|
||||||
|
|
||||||
|
|
||||||
|
def is_formula_correct(formula):
|
||||||
|
""" Run all test on formula """
|
||||||
|
if not formula:
|
||||||
|
return True
|
||||||
|
|
||||||
|
else:
|
||||||
|
formula = formula.replace(' ', '')
|
||||||
|
return all([check_order(formula), check_parenthesis(formula)])
|
||||||
|
|
||||||
|
|
||||||
|
def check_parenthesis(formula: str) -> bool:
|
||||||
|
""" Check if all brackets are opened and closed correctly """
|
||||||
|
stack_of_expected_sings = []
|
||||||
|
|
||||||
|
for sign in formula:
|
||||||
|
if sign in SupportSign.symbols_open:
|
||||||
|
inverse_of_sign = SupportSign.get_closed_symbol(sign)
|
||||||
|
stack_of_expected_sings.append(inverse_of_sign)
|
||||||
|
elif sign in SupportSign.symbols_close:
|
||||||
|
if stack_of_expected_sings.pop() != sign:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return not stack_of_expected_sings
|
||||||
|
|
||||||
|
|
||||||
|
def check_order(formula: str) -> bool:
|
||||||
|
""" Check if all sings have correct preceding and next sign """
|
||||||
|
expected_sign = []
|
||||||
|
|
||||||
|
for sign in formula:
|
||||||
|
if sign in SupportSign.symbols:
|
||||||
|
continue
|
||||||
|
if expected_sign and sign not in expected_sign:
|
||||||
|
return False
|
||||||
|
if sign in Negation.symbols:
|
||||||
|
expected_sign = SentenceVariable.symbols
|
||||||
|
elif sign in SentenceConjunction.symbols:
|
||||||
|
expected_sign = Negation.symbols + SentenceVariable.symbols
|
||||||
|
elif sign in SentenceVariable.symbols:
|
||||||
|
expected_sign = SentenceConjunction.symbols
|
||||||
|
|
||||||
|
return any(symbol in expected_sign for symbol in SentenceVariable.symbols)
|
0
requirements.txt
Normal file
0
requirements.txt
Normal file
9
run.py
Normal file
9
run.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from logic_formula_checker import is_formula_correct
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
formula = input('Type your formula to check: ')
|
||||||
|
if is_formula_correct(formula):
|
||||||
|
print('Formula is correct')
|
||||||
|
else:
|
||||||
|
print('Formula is incorrect')
|
26
tests.py
Normal file
26
tests.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import unittest
|
||||||
|
from logic_formula_checker.utils import *
|
||||||
|
from logic_formula_checker.types import *
|
||||||
|
|
||||||
|
|
||||||
|
class TestsLogicallySentenceChecker(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_check_parenthis(self):
|
||||||
|
correct_formula_short = '[a∧b]'
|
||||||
|
incorrect_formula_short = '[a∧b'
|
||||||
|
self.assertTrue(check_parenthesis(correct_formula_short))
|
||||||
|
self.assertFalse(check_parenthesis(incorrect_formula_short))
|
||||||
|
|
||||||
|
def test_check_formula(self):
|
||||||
|
correct_formula_short = '[a∧b!∧b]'
|
||||||
|
incorrect_formula_short = '[a∧b∧'
|
||||||
|
self.assertTrue(check_parenthesis(correct_formula_short))
|
||||||
|
self.assertFalse(check_parenthesis(incorrect_formula_short))
|
||||||
|
|
||||||
|
def test_get_closed_symbol(self):
|
||||||
|
self.assertEqual(')', SupportSign.get_closed_symbol('('))
|
||||||
|
self.assertNotEqual(']', SupportSign.get_closed_symbol('{'))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user