File: ask_update.py

package info (click to toggle)
sympy 1.14.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 36,784 kB
  • sloc: python: 460,598; xml: 359; makefile: 162; sh: 59; lisp: 4
file content (150 lines) | stat: -rwxr-xr-x 4,330 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python

""" Update the ``ask_generated.py`` file.

This must be run each time ``known_facts()`` in ``assumptions.facts`` module
is changed.

This must be run each time ``_generate_assumption_rules()`` in
``sympy.core.assumptions`` module is changed.

Should be run from sympy root directory.

$ python bin/ask_update.py
"""

# hook in-tree SymPy into Python path, if possible
import os
import sys
from pathlib import Path

isympy_path = os.path.abspath(__file__)
isympy_dir = os.path.dirname(isympy_path)
sympy_top = os.path.split(isympy_dir)[0]
sympy_dir = os.path.join(sympy_top, 'sympy')

if os.path.isdir(sympy_dir):
    sys.path.insert(0, sympy_top)

from sympy.core.assumptions import _generate_assumption_rules
from sympy.assumptions.cnf import CNF, Literal
from sympy.assumptions.facts import (get_known_facts,
    generate_known_facts_dict, get_known_facts_keys, get_matrix_facts, get_number_facts)
from sympy.core import Symbol
from textwrap import dedent, wrap

def generate_code():

    LINE = ",\n        "
    HANG = ' '*8
    code_string = dedent('''\
    """
    Do NOT manually edit this file.
    Instead, run ./bin/ask_update.py.
    """

    from sympy.assumptions.ask import Q
    from sympy.assumptions.cnf import Literal
    from sympy.core.cache import cacheit

    @cacheit
    def get_all_known_facts():
        """
        Known facts between unary predicates as CNF clauses.
        """
        return {
            %s
        }

    @cacheit
    def get_all_known_matrix_facts():
        """
        Known facts between unary predicates for matrices as CNF clauses.
        """
        return {
            %s
        }

    @cacheit
    def get_all_known_number_facts():
        """
        Known facts between unary predicates for numbers as CNF clauses.
        """
        return {
            %s
        }

    @cacheit
    def get_known_facts_dict():
        """
        Logical relations between unary predicates as dictionary.

        Each key is a predicate, and item is two groups of predicates.
        First group contains the predicates which are implied by the key, and
        second group contains the predicates which are rejected by the key.

        """
        return {
            %s
        }
    ''')

    x = Symbol('x')
    fact = get_known_facts(x)
    matrix_fact = get_matrix_facts(x)
    number_fact = get_number_facts(x)

    # Generate CNF of facts between known unary predicates
    cnf = CNF.to_CNF(fact)
    all_clauses = LINE.join(sorted([
        'frozenset(('
         + ', '.join(str(Literal(lit.arg.function, lit.is_Not))
                     for lit in sorted(clause, key=str))
        + '))' for clause in cnf.clauses]))

    # Generate CNF of matrix facts
    cnf = CNF.to_CNF(matrix_fact)
    matrix_clauses = LINE.join(sorted([
        'frozenset(('
         + ', '.join(str(Literal(lit.arg.function, lit.is_Not))
                     for lit in sorted(clause, key=str))
        + '))' for clause in cnf.clauses]))

    # Generate CNF of number facts
    cnf = CNF.to_CNF(number_fact)
    number_clauses = LINE.join(sorted([
        'frozenset(('
         + ', '.join(str(Literal(lit.arg.function, lit.is_Not))
                     for lit in sorted(clause, key=str))
        + '))' for clause in cnf.clauses]))

    # Generate dictionary of facts between known unary predicates
    keys = [pred(x) for pred in get_known_facts_keys()]
    mapping = generate_known_facts_dict(keys, fact)
    items = sorted(mapping.items(), key=str)
    keys = [str(i[0]) for i in items]
    values = ['(set(%s), set(%s))' % (sorted(i[1][0], key=str),
                                      sorted(i[1][1], key=str))
              for i in items]
    m = LINE.join(['\n'.join(
        wrap("{}: {}".format(k, v),
            subsequent_indent=HANG,
            break_long_words=False))
        for k, v in zip(keys, values)]) + ','

    return code_string % (all_clauses, matrix_clauses, number_clauses, m)

code = generate_code()
Path('sympy/assumptions/ask_generated.py').write_text(code)

representation = _generate_assumption_rules()._to_python()
code_string = dedent('''\
"""
Do NOT manually edit this file.
Instead, run ./bin/ask_update.py.
"""

%s
''')
code = code_string % (representation,)
Path('sympy/core/assumptions_generated.py').write_text(code)