Пример #1
0
def main():
    # P = preference_generator(2, 3)
    # print("Preferences P:")
    # print(P)
    f_rng = SCF("Random Choice", random_choice)
    #f_con = SCF("Condorcet", condorcet)
    f_plur = SCF("Plurality", plurality)
    g = Generator(2, 2, mode="bruteforce", max_m=4, max_n=3)
    a = Axiom("resolute", resolute)
    a.check_axiom(g, f_plur)
Пример #2
0
    def generate(self,
                 numAbstractions,
                 numNodesPerLayer,
                 abstractionsMax=False,
                 nodesPerLayerMax=False):
        if abstractionsMax:
            numAbstractions = randint(1, numAbstractions)

        for i in range(numAbstractions):
            aL = AbstractionLayer()
            if nodesPerLayerMax:
                numNodesPerLayer = randint(
                    len(self.outputNodes),
                    numNodesPerLayer)  # ensures diminishing tree to the right
            if i > 0:
                self.abstractionLayers.append(
                    aL.create(self.abstractionLayers[i - 1].nodes))
            else:
                self.abstractionLayers.append(aL.create(self.inputNodes))

            for j in range(numNodesPerLayer):
                aL.addNewNode()

        for outNode in self.outputNodes:
            axOut = []

            for prevN in self.abstractionLayers[-1].nodes:
                ax = Axiom(prevN, outNode, sigmoid(uniform(-1, 1)))
                axOut.append(ax)

            self.axiomOutList.extend(axOut)

        return self
Пример #3
0
    def addNewNode(self):
        axIn = []
        node = NodeFactory.create()

        for prevN in self.prevLayerNodes:
            ax = Axiom(prevN, node, sigmoid(uniform(-1, 1)))
            axIn.append(ax)

        node.assignAxioms(axIn)
        self.nodes.append(node)
        self.axiomList.extend(axIn)
Пример #4
0
def dfs(narr,
        axioms,
        debug=False,
        maxsteps=150,
        animation_mode=False,
        printTrim=False):
    any_err = None
    try:
        next_steps = [(narr, None, Axiom(name='原式'), -1)]
        return_steps = []
        cnt = 0
        while len(next_steps) > 0:
            narr, ani_narr, axiom, axiom_idx = next_steps[0]

            output_narr = deepcopy(narr)
            #print('[output narr]', narr)

            if animation_mode:
                if printTrim:
                    rich.print('[blue]before trim[/]')
                    expression.narr_prettyprint(narr)
                    print('[tex]', expression.narr2tex(narr))
                expression.trim_animations(narr)
                if printTrim:
                    rich.print('[blue]after trim[/]')
                    expression.narr_prettyprint(narr)
                    print('[tex]', expression.narr2tex(narr))

            return_steps.append((output_narr, ani_narr, axiom, axiom_idx))
            next_steps = possible_next_steps(narr,
                                             axioms,
                                             state.value_v1,
                                             animation_mode=animation_mode,
                                             fast_return=True,
                                             debug=debug)
            if cnt > maxsteps:
                any_err = "maximum steps reached."
                break
            cnt += 1
    except KeyboardInterrupt:
        pass

    return return_steps, any_err
Пример #5
0
        n_steps += len(steps)
        print(f'steps: {len(steps)}')
        print(f'test case: {i} / {len(testcases)}')

        #input('Enter to continue...')

    timer.show_stats(n_steps=n_steps)


if __name__ == '__main__':
    if False:
        all_axioms = [
            Axiom(name='负号乘进因子',
                  recursive_apply=True,
                  strict_simplify=True,
                  disable=False).add_rule(
                      '-(x + *{1}) *{2} ',
                      '(-x - *{1}) *{2}',
                      animation='`-(x + *{1})`[replace]{-x - *{1}} *{2}').
            add_test('-(3 - 2)x', '(-3 + 2) \\times x')
        ]

    else:
        from common_axioms import common_axioms
        all_axioms = common_axioms()

    args = sys.argv[1:]
    if len(args) > 0:
        tex = args[0]
        narr = expression.tex2narr(tex)
        steps, err = dfs(narr, all_axioms, debug=False, animation_mode=True)
Пример #6
0
    b = get_atom_number(rewrite_rules['b'])

    if a != None and b != None:
        c = a + b
        rewrite_rules['c'] = gen_atom_number(c)
        new_narr = rewrite_by_alpha(output_tempalate, rewrite_rules)
        return new_narr, True

    return narr, False

calc_add = (
    Axiom(name='加减法计算', root_sign_reduce=False)
    .add_rule('#(a + b)', 'c', animation='`#1(a + b)`[replace]{c}', dynamic_procedure=_calc_add)

    .add_test('-12 + 3', '-9')
    .add_test('(-12 - 3 - 1)', ['-15 - 1', '-13 - 3', '-4 - 12'])
    .add_test('-(12 - 1)', '-11')
    .add_test('-(1 + 14 + 2)', ['-(15 + 2)', '-(3 + 14)', '-(16 + 1)'])
    .add_test('0.25 - 3.25', '-3')
    .add_test('-(1 + 3) x + 3 y', '-4 \\times x + 3 \\times y')
)


def _calc_mul(pattern_narr, signs, narr, rewrite_rules, output_tempalate):
    a = get_atom_number(rewrite_rules['a'])
    b = get_atom_number(rewrite_rules['b'])

    if a != None and b != None:
        c = a * b
        rewrite_rules['c'] = gen_atom_number(c)
        return rewrite_by_alpha(output_tempalate, rewrite_rules), True
Пример #7
0
            print('\t', ani_tex)
        print('\t', tex)


def nn_value(narr):
    tex = expression.narr2tex(narr)
    expr_val, _ = nn.predict_value(tex, nn_models)
    return expr_val


if __name__ == '__main__':

    if False:
        all_axioms = [
            Axiom(name='乘积写成乘方的形式', allow_complication=True).add_rule(
                '#(#X)(#X)',
                '#0 X^{2}',
                animation='`#1(#2 X)(#3 X)`[replace]{#0 X^{2}}')
        ]

    else:
        from common_axioms import common_axioms
        all_axioms = common_axioms(full=True)

    testcase = (
        "(-3 - \\frac{4}{17}) \\times (14 + \\frac{13}{15}) - (3 + \\frac{4}{17}) \\times (2 + \\frac{2}{15})"
    )

    debug_NN = True

    if debug_NN:
        global nn_models
Пример #8
0
def mcts(narr0,
         all_axioms,
         sample_depth=4,
         n_sample_times=200,
         n_maxsteps=100,
         k=3,
         debug=False,
         nn_models=False,
         training=False,
         force_single_thread=False):
    #       q  n   narr  father  axiom   axiomIdx  children
    root = [0, 1, narr0, None, None, -1, []]
    moves = [root]

    render_steps([(narr0, None, -1)])

    global manager
    if not force_single_thread:
        # prepare proxy structure for parallel processes
        root[6] = manager.list([])
        root = manager.list(root)
        moves = [root]
    else:
        manager = None

    node = root
    visited = set([expression.narr2tex(narr0)])
    final_steps = []

    while True:
        q, n, narr, father, axiom, axiom_idx, children = node

        # debug print
        if True:
            #if debug:
            print('\033[94m', end='')
            expr_val = state_value(narr)
            print(f'[current] step={len(moves)}, val={expr_val:.1f}:',
                  expression.narr2tex(narr),
                  end='')
            print('\033[0m', end='\n')
            expression.narr_prettyprint(narr)

        steps, step_probs = policy_steps(narr,
                                         all_axioms,
                                         k=k,
                                         debug=debug,
                                         nn_models=nn_models)

        if debug:
            rich.print(f'[magenta]Candidate steps: {len(steps)}[/]')
            for i, (n, a, ai) in enumerate(steps):
                val = state_value(n)
                rich.print(f'[red]#{i+1}[/]', a.name(), ':', end=' ')
                rich.print(f'val={val:.2f}', end=' ')
                print(expression.narr2tex(n), end='\n\n')

            if False:
                from axiom import Axiom
                render_steps([(narr, Axiom(), -1)] + steps, show_index=True)
                choices = input('Limit choices: ')
                choices = [
                    i for i in map(lambda x: int(x), choices.split(','))
                ]
                rich.print(choices)
                steps = [steps[i - 1] for i in choices]

        if len(steps) == 0:
            if debug: print('[no more candidate steps]')
            if nn_models and training:
                policy = 0
                #policy_fine_tuning(nn_models, expr, policy, debug=debug, all_axioms=all_axioms)
            break

        if manager and not force_single_thread:
            evaluate_parallel(node,
                              all_axioms,
                              steps,
                              n_sample_times,
                              sample_depth,
                              visited,
                              debug=debug,
                              nn_models=nn_models,
                              k=k,
                              step_probs=step_probs)
        else:
            evaluate(node,
                     all_axioms,
                     steps,
                     n_sample_times,
                     sample_depth,
                     visited,
                     debug=debug,
                     nn_models=nn_models,
                     k=k,
                     step_probs=step_probs)

        # selection
        move_choice, w, _ = best_child_of(node, c_param=.0, debug=debug)
        move_to_expr = expression.narr2tex(move_choice[2])
        if w == 0 or move_to_expr in visited:
            print(
                f'[abort] best w={w:.2f}, visited: {move_to_expr in visited}')
            break
        else:
            if nn_models and training:
                policy = move_choice[5] + 1
                #policy_fine_tuning(nn_models, expr, policy, debug=debug, all_axioms=all_axioms)

            moves.append(move_choice)
            node = move_choice

            # construct steps to be returned
            final_steps = [(e, a, ai) for q, n, e, f, a, ai, c in moves]
            render_steps(final_steps)

            visited.add(move_to_expr)
            #if debug: print('[visited]', visited)

            if len(moves) >= n_maxsteps:
                if debug: print('[exceed max steps]')
                break

    if len(final_steps) > 0:
        final_steps = back_off_step(final_steps, debug=True)

    if nn_models and training:
        # fine-tune value network
        for i, (e, _, _) in enumerate(final_steps):
            value = -(len(final_steps) - i - 1)
            #value_fine_tuning(nn_models, e, value, debug=debug)
    return final_steps
Пример #9
0
def common_axioms(full=False):
    """
    常用的规则集合(优先级已经按照数组元素的索引确定)
    """
    axioms = []

    axioms.append(dynamic_axioms.canonicalize)

    axioms.append(
        Axiom(name='一个数减去它本身是零', root_sign_reduce=False).add_rule(
            '#(n - n)', '0', animation='`#1(n - n)`[replace]{0}').add_rule(
                '#(a - \\frac{a}{1})',
                '0',
                animation='`#1(a - \\frac{a}{1})`[replace]{0}').add_rule(
                    '#(\\frac{a}{1} - a)',
                    '0',
                    animation='`#1(\\frac{a}{1} - a)`[replace]{0}').add_test(
                        '-(3 - 3 + 1)'))

    axioms.append(
        Axiom(name='任何数乘以零还是零',
              recursive_apply=True).add_rule(
                  '# 0 \cdot *{1}',
                  '0',
                  animation='`#1 0 \cdot *{1}`[replace]{0}').add_rule(
                      '#\\frac{#0}{x}',
                      '0',
                      animation='`#1 \\frac{#2 0}{x}`[replace]{0}').add_test(
                          '0 a b'))

    axioms.append(
        Axiom(name='带分式的展开', allow_complication=True).add_rule(
            '# & \\frac{a}{b}',
            '#1 (v + \\frac{a}{b})',
            animation="`#1 & \\frac{a}{b}`[replace]{#1 (v + \\frac{a}{b})}").
        add_test('-3 \\frac{-2}{4}',
                 '-(3 + \\frac{-2}{4})').add_test('-3 \\frac{1}{2}',
                                                  '-(3 + \\frac{1}{2})'))

    axioms.append(
        Axiom(name='任何数加零还是它本身', recursive_apply=True,
              root_sign_reduce=False).add_rule(
                  '#(0 + n)', 'n', animation='`0`[remove] + n').add_rule(
                      '#(n - 0)', 'n', animation='n - `0`[remove]').add_test(
                          '0+3+2').add_test('-(0+3+2)'))

    axioms.append(
        Axiom(name='一乘以任何数还是它本身', recursive_apply=True).add_rule(
            '# 1 \\times *{1}',
            '#1 *{1}', animation='#1 `1`[remove] *{1}').add_test(
                '1 \cdot 4', '4').add_test('-4 \\times 1', '-4').add_test(
                    '- (a+b) \cdot 1',
                    '-a - b').add_test('- 1 \cdot 4 \cdot 1', '-4'))

    axioms.append(
        Axiom(name='根号的平方是其本身').add_rule(
            '#(#\\sqrt{x})^{2}',
            '#1 x',
            animation='`#1 (#2\\sqrt{x})^{2}`[replace]{#1 x}'))

    axioms.append(
        Axiom(name='一的平方还是一').add_rule(
            '#(# 1)^{2}', '#1 1',
            animation='`#1 (#2 1)^{2}`[replace]{#1 1}').add_test(
                '-1^{2}').add_test('(-1)^{2}'))

    axioms.append(
        Axiom(name='负数的平方是其相反数的平方', strict_simplify=(not full)).add_rule(
            '#(-a)^{2}',
            '#1 a^{2}',
            animation='`#1 (-a)^{2}`[replace]{#1 a^{2}}').add_test(
                '(-3)^{2} - (6 \div (-\\frac{2}{3})^{2}) -  (-2)^{2}').
        add_test('(6 \div (-\\frac{2}{3})^{2})').add_test(
            '3^{2} - (1 + \\frac{1}{2}) \\times \\frac{2}{9} - (6 \div (-\\frac{2}{3})^{2}) - (-2)^{2}'
        ))

    axioms.append(
        Axiom(name='除以一个数等于乘上它的倒数', allow_complication=True).add_rule(
            '# (#\\frac{w}{x}) \\div (# \\frac{y}{z})',
            '#0 \\frac{wz}{xy}',
            animation=
            '`#1 (#2 \\frac{w}{x}) \\div (#3 \\frac{y}{z})`[replace]{#0 \\frac{wz}{xy}}'
        ).add_rule(
            '# x \\div (# \\frac{y}{z})',
            '#0 \\frac{xz}{y}',
            animation='`#1 x \\div (#2 \\frac{y}{z})`[replace]{#0 \\frac{xz}{y}}'
        ).add_test('- 3 \\div (-\\frac{1}{2})',
                   '-\\frac{3 \\times 2}{1}').add_test(
                       '\\frac{2}{3} \div \\frac{4}{5}'))

    axioms.append(
        Axiom(name='以分数表示除法', allow_complication=True).add_rule(
            '# (#x) \\div (#y)',
            '#0 \\frac{x}{y}',
            animation="`#1(#2 x) \\div (#3 y)`[replace]{#0 \\frac{x}{y}}").
        add_test('1 \\div 2x + 3').add_test("6 \div 3"))

    axioms.append(
        Axiom(name='因子和分母消去').add_rule(
            '# x \\times \\frac{a}{x}',
            '#1 a',
            animation="#1 `x`[remove] \\times \\frac{a}{`x`[removeDenom]}").
        add_test('-3 \\times \\frac{-2}{3}',
                 '2').add_test('3 \\times \\frac{-2}{3}', '-2'))

    axioms.append(
        Axiom(name='绝对值分配到分子分母中', allow_complication=True).add_rule(
            '# \\left| # \\frac{a}{b} \\right|',
            '#1 \\frac{\\left| a \\right|}{\\left| b \\right|}',
            animation=
            '`#1 \\left| #2 \\frac{a}{b} \\right|`[replace]{#1 \\frac{\\left| a \\right|}{\\left| b \\right|}}'
        ).add_test('\\left| - \\frac{1}{2} \\right|'))

    axioms.append(
        Axiom(name='根号分配到分子分母中', allow_complication=True).add_rule(
            '# \\sqrt{\\frac{a}{b}}',
            '#1 \\frac{\\sqrt{a}}{\\sqrt{b}}',
            animation=
            '`#1 \\sqrt{\\frac{a}{b}}`[replace]{#1 \\frac{\\sqrt{a}}{\\sqrt{b}} }'
        ).add_test('- \sqrt{\\frac{1}{2}}'))

    axioms.append(
        Axiom(name='分子分母消除公因子', recursive_apply=True).add_rule(
            '# \\frac{# x *{1} }{# x *{2} }',
            '#1 \\frac{#2 *{1}}{#3 *{2}}',
            animation='#1 \\frac{#2 `x`[remove] *{1}}{#3 `x`[remove] *{2}}'
        ).add_rule(
            '# \\frac{# x }{# x *{2} }',
            '#0 \\frac{1}{*{2}}',
            animation='#0 \\frac{`x`[replace]{1} \\times 1}{`x`[remove] *{2}}'
        ).add_rule('# \\frac{# x *{1} }{# x }',
                   '#0 *{1}',
                   animation='#0 \\frac{`x`[remove] *{1} }{`x`[removeDenom]}').
        add_rule('# \\frac{# x}{# x}',
                 '#0 1',
                 animation='`#1 \\frac{#2 x}{#3 x}`[replace]{#0 1}').add_test(
                     '- \\frac{bx}{ax}',
                     '-\\frac{b}{a}').add_test('- \\frac{-bx}{xa}',
                                               '-\\frac{-b}{a}').add_test(
                                                   '- \\frac{-bxy}{-xay}',
                                                   '-\\frac{-b}{-a}').add_test(
                                                       '- \\frac{-x}{ax}',
                                                       '\\frac{1}{a}').
        add_test('\\frac{-x}{xay}', '\\frac{-1}{a \\times y}').add_test(
            '\\frac{3xy}{-xy}', '-3').add_test(
                '-\\frac{-a}{-a}',
                '-1').add_test('\\frac{-(a + b)}{a + b}', '-1').add_test(
                    '\\frac{-3 - \\frac{1}{3}}{-(3 + \\frac{1}{3}) \\times x}',
                    '\\frac{-1}{-x}'))

    axioms.append(
        Axiom(name='乘积写成乘方的形式', allow_complication=True).add_rule(
            '#(#X)(#X)',
            '#0 X^{2}',
            animation='`#1(#2 X)(#3 X)`[replace]{#0 X^{2}}').add_test(
                'xx').add_test('-\\frac{1}{2} \cdot \\frac{1}{2}',
                               '-(\\frac{1}{2})^{2}'))

    axioms.append(dynamic_axioms.calc_add)
    axioms.append(dynamic_axioms.calc_mul)
    axioms.append(dynamic_axioms.calc_pow)
    axioms.append(dynamic_axioms.calc_sqrt)
    axioms.append(dynamic_axioms.calc_abs)
    axioms.append(dynamic_axioms.collapse_fraction_add_float)
    axioms.append(dynamic_axioms.simplify_fraction)
    axioms.append(dynamic_axioms.collapse_fraction)
    axioms.append(dynamic_axioms.calc_sqrt)

    axioms.append(
        Axiom(name='等式移项')
        #.add_rule('#x # y = z', '#1 x #2 y -z=0', animation='#1 x #2 y - `z`[moveAfter,1] = `z`[moveBefore,1] + `0`[add]')
        .add_rule('x = z',
                  'x - z = 0',
                  animation='x - `z`[add] = `z`[replace]{0}').add_test(
                      '1 - 2 = -3 + 5', '1 - 2 + 3 - 5 = 0').add_test(
                          'ax = bx', 'a \\times x - b \\times x = 0'))

    axioms.append(
        Axiom(name='等式两边同乘', allow_complication=True).add_rule(
            '#\\frac{x}{y} + *{1} = z',
            '#1 x + y(*{1}) = yz',
            animation=
            '#1 \\frac{x}{`y`[removeDenom]} + `y`[add](*{1}) = `y`[add] z').
        add_rule(
            '#\\frac{x}{y} = z',
            '#1 x = yz',
            animation='#1 \\frac{x}{`y`[removeDenom]} = `y`[add] z').add_test(
                '-\\frac{-2}{-3} = -4', '2 = (-3) \\times (-4)').add_test(
                    '\\frac{x}{2} + a - b = z',
                    'x + 2 \\times (a - b) = 2 \\times z'))

    if full:
        tmp_axiom = (Axiom(
            name='合并同类项',
            recursive_apply=True,
            allow_complication=True,
            root_sign_reduce=False,
            max_results=4
        ).add_rule(
            '#(x + x)', '2x', animation='`#1(x + x)`[replace]{2x}'
        ).add_rule(
            '#(-x - x)', '-2x', animation='`#1(-x - x)`[replace]{-2x}'
        ).add_rule(
            '#(#x # kx)',
            '(#2 1 #3 k) x',
            animation='`#1(#2 x #3 kx)`[replace]{(#2 1 #3 k) x}'
        ).add_rule(
            '#(#x # xk)',
            '(#2 1 #3 k) x',
            animation='`#1(#2 x #3 xk)`[replace]{(#2 1 #3 k) x}'
        ).add_rule(
            '#(#x *{1} # x *{2})',
            '(#2 *{1} #3 *{2}) x',
            animation='`#1(#2 x *{1} #3 x *{2})`[replace]{(#2 *{1} #3 *{2}) x}'
        ))
    else:
        tmp_axiom = (Axiom(
            name='合并同类项',
            recursive_apply=True,
            allow_complication=True,
            root_sign_reduce=False,
            max_results=4
        ).add_rule(
            '#(X + X)', '2X', animation='`#1(X + X)`[replace]{2X}'
        ).add_rule(
            '#(-X - X)', '-2X', animation='`#1(-X - X)`[replace]{-2X}'
        ).add_rule(
            '#(#X # kX)',
            '(#2 1 #3 k) X',
            animation='`#1(#2 X #3 kX)`[replace]{(#2 1 #3 k) X}'
        ).add_rule(
            '#(#X # Xk)',
            '(#2 1 #3 k) X',
            animation='`#1(#2 X #3 Xk)`[replace]{(#2 1 #3 k) X}'
        ).add_rule(
            '#(#X *{1} # X *{2})',
            '(#2 *{1} #3 *{2}) X',
            animation='`#1(#2 X *{1} #3 X *{2})`[replace]{(#2 *{1} #3 *{2}) X}'
        ))

    axioms.append(
        tmp_axiom.add_test('a + a', '2 \\times a').add_test(
            '-a - a', '2 \\times (-a)').add_test(
                'x^{2} + x^{2}',
                '2 \\times x^{2}').add_test('-(-x + 3x)').add_test(
                    '-x + 3x - 1x').add_test('(-1-1)x').add_test(
                        '-(-x + 3x - 1x)').add_test('x + 2x + 3x').add_test(
                            'x - 3 \cdot x', '(1 - 3) \\times x'))

    axioms.append(
        Axiom(name='负号提出括号', strict_simplify=True,
              disable=(not full)).add_rule(
                  '+(x + *{1})',
                  '-(-x - *{1})',
                  animation='`+(x + *{1})`[replace]{-(-x - *{1})}').
        add_test("(1 + 2 + 3)").add_test("(-a - b) x").add_test(
            "(-a + b)x").add_test("(-a - b - c) x").add_test(
                '-3-\\frac{4}{17}').add_test('(-3-\\frac{4}{17}) x').add_test(
                    '(-3-\\frac{4}{17}) x + y').add_test("(a - b - c) x"))

    axioms.append(
        Axiom(name='嵌套分式的化简').add_rule(
            '#\\frac{#\\frac{x}{y}}{#\\frac{a}{b}}',
            '#0 \\frac{bx}{ay}',
            animation=
            '`#1 \\frac{#2 \\frac{x}{y}}{#3 \\frac{a}{b}}`[replace]{#0 \\frac{bx}{ay}}'
        ).add_rule(
            '#\\frac{#1}{#\\frac{x}{y}}',
            '#0 \\frac{y}{x}',
            animation=
            '`#1 \\frac{#2 1}{#3 \\frac{x}{y}}`[replace]{#0 \\frac{y}{x}}'
        ).add_rule(
            '#\\frac{#\\frac{x}{y}}{#1}',
            '#0 \\frac{x}{y}',
            animation=
            '`#1 \\frac{#2 \\frac{x}{y}}{#3 1}`[replace]{#0 \\frac{x}{y}}').
        add_rule('#\\frac{a}{#\\frac{x}{y}}',
                 '#0 \\frac{ay}{x}',
                 animation=
                 '`#1 \\frac{a}{#2 \\frac{x}{y}}`[replace]{#0 \\frac{ay}{x}}').
        add_rule('#\\frac{#\\frac{x}{y}}{a}',
                 '#0 \\frac{x}{ay}',
                 animation=
                 '`#1 \\frac{#2 \\frac{x}{y}}{a}`[replace]{#0 \\frac{x}{ay}}').
        add_test('-\\frac{-\\frac{4}{3}}{-\\frac{4}{3}}', '-1').add_test(
            '-\\frac{-\\frac{4}{3}}{\\frac{1}{2}}',
            '\\frac{2 \\times 4}{1 \\times 3}').add_test(
                '-\\frac{-\\frac{4}{3}}{x}',
                '\\frac{4}{x \\times 3}').add_test('-\\frac{4}{-\\frac{4}{3}}',
                                                   '\\frac{4 \\times 3}{4}').
        add_test('\\frac{-8}{\\frac{1}{4}}').add_test(
            '\\frac{-18}{\\frac{9 \\times (1 - \\frac{3}{4})}{4}}'))

    axioms.append(dynamic_axioms.fraction_addition)

    axioms.append(
        Axiom(name='分母为一的分式化简').add_rule(
            '#\\frac{k}{#1}',
            '#0 k',
            animation='`#1 \\frac{k}{#2 1}`[replace]{#0 k}').add_test(
                '\\frac{3}{-1}', '-3'))

    axioms.append(
        Axiom(name='分式的乘法', allow_complication=True).add_rule(
            '#\\frac{#1}{x} \\frac{#1}{y}',
            '#0 \\frac{1}{xy}',
            animation=
            '`#1 \\frac{#2 1}{x} \\frac{#3 1}{y}`[replace]{#0 \\frac{1}{xy}}').
        add_rule(
            '#\\frac{#1}{x} \\frac{y}{#1}',
            '#0 \\frac{y}{x}',
            animation=
            '`#1 \\frac{#2 1}{x} \\frac{y}{#3 1}`[replace]{#0 \\frac{y}{x}}').
        add_rule(
            '#\\frac{x}{#1} \\frac{y}{#1}',
            '#0 xy',
            animation='`#1 \\frac{x}{#2 1} \\frac{y}{#3 1}`[replace]{#0 xy}'
        ).add_rule('#\\frac{a}{c} \\frac{b}{d}',
                   '#1 \\frac{ab}{cd}',
                   animation=
                   '`#1 \\frac{a}{c} \\frac{b}{d}`[replace]{#1 \\frac{ab}{cd}}'
                   ).add_test('-\\frac{1}{-2} \cdot \\frac{-2}{1}',
                              '-\\frac{-2}{-2}'))

    axioms.append(
        Axiom(name='乘数的指数是各个因子指数的乘数',
              recursive_apply=True,
              allow_complication=True).
        add_rule(
            '# (# a *{1})^{k}',
            '#1 (#2 a)^{k} \\times (*{1})^{k}',
            animation=
            '`#1 (#2 a *{1})^{k}`[replace]{#1 (#2 a)^{k} \\times (*{1})^{k}}').
        add_test('-(-3xy)^{2}', '-(-3)^{2} \\times x^{2} \\times y^{2}'))

    axioms.append(
        Axiom(name='将指数分配进分子分母', allow_complication=True).add_rule(
            '#(-\\frac{#a}{#b})^{k}',
            '#1 (-1)^{k} \\frac{(#2 a)^{k}}{(#3 b)^{k}}',
            animation=
            '`#1 (-\\frac{#2 a}{#3 b})^{k}`[replace]{#1 (-1)^{k} \\frac{(#2 a)^{k}}{(#3 b)^{k}}}'
        ).add_rule(
            '#(+\\frac{#a}{#b})^{k}',
            '#1 \\frac{(#2 a)^{k}}{(#3 b)^{k}}',
            animation=
            '`#1 (+\\frac{#2 a}{#3 b})^{k}`[replace]{#1 \\frac{(#2 a)^{k}}{(#3 b)^{k}}}'
        ).add_test('(-\\frac{-2}{3})^{2}',
                   '(-1)^{2} \\times \\frac{(-2)^{2}}{3^{2}}').add_test(
                       '-(\\frac{-2}{3})^{2}', '-\\frac{(-2)^{2}}{3^{2}}'))

    axioms.append(
        Axiom(name='系数乘进分式的分子', allow_complication=True).add_rule(
            '# a \\times \\frac{# 1}{b}',
            '#0 \\frac{a}{b}',
            animation='`#1 a \\times \\frac{#2 1}{b}`[replace]{#0 \\frac{a}{b}}'
        ).add_rule(
            '# a \\times \\frac{# c}{b}',
            '#0 \\frac{ac}{b}',
            animation='`#1 a \\times \\frac{#2 c}{b}`[replace]{#0 \\frac{ac}{b}}'
        ).add_test('-\\frac{-1}{3} \\times 12', '\\frac{4}{1}').add_test(
            '12 \cdot \\frac{3}{2}', '\\frac{18}{1}').add_test(
                '\\frac{9}{4} \\times (1 - \\frac{3}{4})',
                '\\frac{9 \\times (1 - \\frac{3}{4})}{4}'))

    axioms.append(
        Axiom(name='乘法分配率',
              allow_complication=True,
              recursive_apply=True,
              max_results=4).
        add_rule(
            '#a(x + *{1})',
            '#1 ax #1 a *{1}',
            animation=
            '`#1 a`[moveBefore,1] `(#1 `a`[moveAfter,1] x #1 `a`[moveAfter,1] *{1})`[removeOnly]'
        ).add_test(
            '3(a + b + c) + 1',
            '1 + 3 \\times a + 3 \\times b + 3 \\times c').add_test(
                '(a - b)(-2)',
                '-2 \\times a - 2 \\times (-b)').add_test('2(a + 3(b + c))')
        #.add_test('\\frac{60 \\times (1 - \\frac{2}{5}) + 3}{2}')
    )

    axioms.append(
        Axiom(name='负号乘进因子',
              recursive_apply=True,
              strict_simplify=True,
              disable=(not full)).add_rule(
                  '-(x + *{1}) *{2} ',
                  '(-x - *{1}) *{2}',
                  animation='`-(x + *{1})`[replace]{-x - *{1}} *{2}').add_test(
                      '-(3 - 2)x', '(-3 + 2) \\times x'))

    axioms.append(dynamic_axioms.fraction_int_addition)

    axioms.append(
        Axiom(name='和平方公式', allow_complication=True).add_rule(
            '#(#a + *{1})^{2}',
            '#1 ( a^{2} #2 2 a *{1} + (*{1})^{2} )',
            animation=
            '`#1 (#2 a + *{1})^{2}`[replace]{#1 (a^{2} #2 2 a *{1} + (*{1})^{2})}'
        ).add_rule(
            '# \\left| #a + *{1} \\right|^{2}',
            '#1 ( a^{2} #2 2 a *{1} + (*{1})^{2} )',
            animation=
            '`#1 \\left| #2 a + *{1} \\right|^{2}`[replace]{#1 ( a^{2} #2 2 a *{1} + (*{1})^{2} )}'
        ).add_test('-(3 - 2)^{2}',
                   '-(3^{2} + 2 \\times 3 \\times (-2) + (-2)^{2})'))

    axioms.append(
        Axiom(name='平方差公式', allow_complication=True).add_rule(
            '#(a + *{1})(a - *{1})',
            '#1( a^{2} - (*{1})^{2} )',
            animation=
            '`#1 (a + *{1})(a - *{1})`[replace]{#1( a^{2} - (*{1})^{2} )}').
        add_test('(3 + a + b)(-a - b + 3)',
                 ['3^{2} - (a + b)^{2}', '3^{2} - (-a - b)^{2}']))

    return axioms