Exemplo n.º 1
0
 def _repr_html_(self, context=None, unofficialNameKindContext=None):
     '''
     Generate html to show a png compiled from the latex (that may be recalled
     from memory or storage if it was generated previously) with a link to
     an expr.ipynb notebook for displaying the expression information.
     If 'context' is provided, find the stored expression information in
     that context; otherwise, use the default, current directory Context.
     If 'unofficialNameKindContext' is provided, it should be the 
     (name, kind, context) for a special expression that is not-yet-official
     (%end_[common/axioms/theorems] has not been called yet in the special 
     expressions notebook).
     '''
     if context is None:
         context = Context()
     if not hasattr(self._styleData, 'png'):
         self._styleData.png, png_url = context._stored_png(
             self, self.latex(), self._config_latex_tool)
         self._styleData.png_url = png_url
     if self._styleData.png_url is not None:
         expr_notebook_rel_url = context.expressionNotebook(
             self, unofficialNameKindContext)
         html = '<a class="ProveItLink" href="' + expr_notebook_rel_url + '">'
         encoded_png = encodebytes(self._styleData.png).decode("utf-8")
         html += '<img src="data:image/png;base64,' + encoded_png + r'" style="display:inline;vertical-align:middle;" />'
         html += '</a>'
     # record as a "displayed" (style-specific) expression
     Expression.displayed_expression_styles.add((self._style_id, self))
     return html
Exemplo n.º 2
0
 def __init__(self,
              stringFormat,
              latexFormat=None,
              extraCoreInfo=tuple(),
              context=None):
     '''
     Create a Literal.  If latexFormat is not supplied, the stringFormat is used for both.
     '''
     from proveit._core_.context import Context
     from proveit._core_.expression.expr import Expression
     if context is None:
         # use the default
         context = Context.default
         if context is None:
             # if no default is specified; use the current working directory
             context = Context()
     elif isinstance(context, str):
         # convert a path string to a Context
         if os.path.exists(context):
             # Make a Context given a path.
             context = Context(context)
         else:
             # Make a Context given a name.
             # First create the local context to make sure we have access
             # to context roots referenced by this context.
             Context()
             context = Context.getContext(context)
     Label.__init__(self, stringFormat, latexFormat, 'Literal',
                    (context.name, ) + tuple(extraCoreInfo))
     self._setContext(context)
     #if self._coreInfo in Literal.instances:
     #    raise DuplicateLiteralError("Only allowed to create one Literal with the same context and string/latex formats")
     Literal.instances[self._coreInfo] = self
Exemplo n.º 3
0
 def proving(self, line):
     from proveit._core_.proof import Theorem
     self.context = Context(
         '..'
     )  # the context should be up a directory from the _proofs_ directory
     sys.path.append('..')
     theorem_name, presuming_str = str(line.strip()).split(' ', 1)
     if not presuming_str.find('presuming ') == 0:
         print "Format: %begin_proof <theorem_name> presuming [<list of theorems / context-names>]"
         return
     args = presuming_str.split(' ', 1)[-1].strip('[]').split(',')
     theorem_truth = Context('..').getTheorem(theorem_name).provenTruth
     print "Beginning proof of", theorem_name
     presuming = [arg.strip() for arg in args if arg.strip() != '']
     # The list of theorems/context-names may be composed of full-path strings containing '.'s
     # or may be actual theorem variables defined in the IPython sesson.  The latter
     # instances will be converted to strings.
     for k, arg in enumerate(list(presuming)):
         if '.' not in arg:
             knownTruth = self.shell.user_ns[arg]
             if not isinstance(knownTruth, KnownTruth) or not isinstance(
                     knownTruth.proof(), Theorem):
                 raise ValueError(
                     "Presuming list must be composed of full-path theorem/context-name containing '.'s or be KnownTruth variable representing a Theorem"
                 )
             theorem = knownTruth.proof()
             presuming[k] = str(theorem)  # full path of theorem
     begin_proof_result = theorem_truth.beginProof(presuming)
     if isinstance(begin_proof_result, Expression):
         # assign the theorem name to the theorem expression
         # and display this assignment
         theorem_expr = theorem_truth.expr
         self.shell.user_ns[theorem_name] = theorem_expr
         return Assignments([theorem_name], [theorem_expr],
                            beginningProof=True)
Exemplo n.º 4
0
 def __init__(self,
              stringFormat,
              latexFormat=None,
              extraCoreInfo=tuple(),
              context=None):
     '''
     Create a Literal.  If latexFormat is not supplied, the stringFormat is used for both.
     '''
     from proveit._core_.context import Context
     from proveit._core_.expression.expr import Expression
     if context is None:
         # use the default
         context = Context.default
         if context is None:
             # if no default is specified; use the current working directory
             context = Context()
     elif isinstance(context, str):
         # convert a path string to a Context
         context = Context(context)
     self.context = context
     Label.__init__(self, stringFormat, latexFormat, 'Literal',
                    (context.name, ) + tuple(extraCoreInfo))
     #if self._coreInfo in Literal.instances:
     #    raise DuplicateLiteralError("Only allowed to create one Literal with the same context and string/latex formats")
     Literal.instances[self._coreInfo] = self
     Expression.contexts[self] = self.context
Exemplo n.º 5
0
 def proving(self, theorem_name, presumptions, justRecordPresumingInfo=False):
     self.context = Context('..') # the context should be up a directory from the _proofs_ directory
     sys.path.append('..')
     proving_theorem = self.context.getTheorem(theorem_name)
     proving_theorem_truth = proving_theorem.provenTruth
     print("Beginning proof of", theorem_name)
     return proving_theorem_truth.beginProof(proving_theorem, presumptions, justRecordPresumingInfo=justRecordPresumingInfo)
Exemplo n.º 6
0
    def __init__(self):
        self.context = Context()  # context of the current working directory
        self.subContextNames = list(self.context.getSubContextNames())
        self.subContextDescriptions = dict()

        # read the previous 'mode' (interactive or static) and toggle it.
        prev_mode = 'static'  # default toggles 'static' to 'interactive'
        if os.path.isfile('_mode_.txt'):
            with open('_mode_.txt', 'rt') as f:
                prev_mode = f.read().strip()
        # mode toggles between 'static' and 'interactive'
        if prev_mode == 'static':
            self.mode = 'interactive'
            # in interactive mode, sub-contexts are presented in an interactive widget
            self.widget = widgets.VBox()
            self.smallButtonLayout = widgets.Layout(width='30px')
            self.subContextLinkLayout = widgets.Layout(width='20%')
            self.subContextDescriptionLayout = widgets.Layout(width='80%')
        else:
            self.mode = 'static'

        # write the new mode that has been toggled
        with open('_mode_.txt', 'w') as f:
            f.write(self.mode + '\n')

        # register each sub-context name, reading their brief descriptions and
        # creating widgets if in interactive mode
        for sub_context_name in self.subContextNames:
            self._addSubContextRow(sub_context_name)
Exemplo n.º 7
0
    def display_dependencies(self, name, known_truth):
        '''
        Show the dependencies of an axiom or theorem.
        '''
        proof = known_truth.proof()  # Axiom or Theorem

        def displaySpecialStmt(stmt):
            '''
            Given an Axiom or Theorem, display HTML with a link
            to the definition.
            '''
            expr = stmt.provenTruth.expr
            display(
                HTML(
                    '<dt><a class="ProveItLink" href="%s">%s</a></dt><dd>%s</dd>'
                    % (stmt.getLink(), str(stmt), expr._repr_html_())))

        def stmt_sort(stmt):
            return str(stmt)

        if isinstance(proof, Theorem):
            try:
                required_axioms, required_unproven_theorems = proof.allRequirements(
                )
            except:
                display(HTML('<h3>This theorem has not been proven yet.</h3>'))
                required_axioms, required_unproven_theorems = tuple(), tuple()

            if len(required_unproven_theorems) > 0:
                display(
                    HTML(
                        '<h3>Unproven theorems required (directly or indirectly) to prove %s</h3>'
                        % name))
                display(HTML('<dl>'))
                for required_unproven_theorem in sorted(
                        required_unproven_theorems, key=stmt_sort):
                    displaySpecialStmt(
                        Context.findTheorem(required_unproven_theorem))
                display(HTML('</dl>'))
            if len(required_axioms) > 0:
                display(
                    HTML(
                        '<h3>Axioms required (directly or indirectly) to prove %s</h3>'
                        % name))
                display(HTML('<dl>'))
                for required_axiom in sorted(required_axioms, key=stmt_sort):
                    displaySpecialStmt(Context.findAxiom(required_axiom))
                display(HTML('</dl>'))

        dependents = proof.directDependents()
        if len(dependents) == 0:
            display(HTML('<h3>No theorems depend upon %s</h3>' % name))
        else:
            display(HTML('<h3>Theorems that depend directly on %s</h3>' %
                         name))
            display(HTML('<dl>'))
            for dependent in sorted(proof.directDependents(), key=stmt_sort):
                displaySpecialStmt(Context.findTheorem(dependent))
            display(HTML('</dl>'))
Exemplo n.º 8
0
 def show_expr(self):
     '''
     Convenient for debugging when %check_expr fails.
     '''
     _, hash_id = os.path.split(os.path.abspath('.'))
     context = Context()
     stored_expr = context.getStoredExpr(hash_id)
     return stored_expr
Exemplo n.º 9
0
 def check_expr(self, expr_name, expr):
     _, hash_id = os.path.split(os.path.abspath('.'))
     context = Context()
     stored_expr = context.getStoredExpr(hash_id)
     if expr != stored_expr:
         raise ProveItMagicFailure("The built '%s' does not match the stored Expression"%expr_name)
     if expr._style_id != stored_expr._style_id:
         raise ProveItMagicFailure("The built '%s' style does not match that of the stored Expression"%expr_name)
     print("Passed sanity check: built '%s' is the same as the stored Expression."%expr_name)
Exemplo n.º 10
0
 def begin_axioms(self):
     # context based upon current working directory
     self.context = Context()
     if len(self.definitions) > 0 or self.kind is not None:
         if self.kind != 'axioms':
             raise ProveItMagicFailure("Run %%begin_axioms in a separate notebook from %%begin_%s."%self.kind)
         print("WARNING: Re-running %begin_axioms does not reset previously defined axioms.")
         print("         It is suggested that you restart and run all cells after editing axioms.")
     print("Defining axioms for context '" + self.context.name + "'")
     print("Subsequent end-of-cell assignments will define axioms")
     print("%end_axioms will finalize the definitions")
Exemplo n.º 11
0
 def begin(self, line):
     kind = line.strip()
     # context based upon current working directory
     self.context = Context()
     if kind == 'axioms':
         self.begin_axioms()
     elif kind == 'theorems':
         self.begin_theorems()
     elif kind == 'common':
         self.begin_common()
     self.kind = kind
Exemplo n.º 12
0
    def deleteSubContext(self, contextNameToDelete):
        '''
        Delete (unlink) a sub-context with the given name as long as there are not external
        references to its expressions.  Either way, the directory will remain.
        Only files in the __pv_it directories are cleared (recursively in all sub-sub contexts,
        etc) and the current directory's context will no longer link to it.  That is
        why we use the term 'unlinked'.  It may be resurrected by adding the sub-context
        with the same name back in.
        '''
        context = Context(contextNameToDelete)
        # remove all internal references and see if any external references remain
        context.clearAll()
        contains_expressions = context.containsAnyExpression()

        def dismiss(sender):
            if not contains_expressions:
                # Successful removal; we need to remove the deleted sub-context name from
                # the self.subContextNames list, the displayed widgets, and the list in _sub_contexts_.txt.
                new_sub_contexts = []
                new_widget_children = []
                for k, sub_context_name in enumerate(self.subContextNames):
                    if sub_context_name != contextNameToDelete:
                        new_sub_contexts.append(sub_context_name)
                        new_widget_children.append(self.widget.children[k])
                self.subContextNames = new_sub_contexts
                self.updateSubContextNames()
                self.widget.children = new_widget_children
            else:
                # dismiss the delete confirmation/message by removing all but the first row in the row_widget
                row_widget.children = (row_widget.children[0], )

        if not contains_expressions:
            msg = 'Removing (unlinking) sub-context; add it again to resurrect it or delete the directory to make it permanent'
            msg_width = '650px'
        else:
            msg = "Context removal cancelled; there are external references to its expressions (or corrupted '__pv_it' directories)"
            msg_width = '650px'
        row_widget = self.widget.children[self.subContextNames.index(
            contextNameToDelete)]
        delete_msg = widgets.Label(msg,
                                   layout={
                                       'width': msg_width,
                                       'max_width': msg_width
                                   })
        gotit_button = widgets.Button(description='got it',
                                      disabled=False,
                                      tooltip='got it',
                                      layout={'width': '80px'})
        gotit_button.on_click(dismiss)
        row_widget.children = (row_widget.children[0],
                               widgets.HBox([delete_msg, gotit_button],
                                            layout=widgets.Layout(
                                                justify_content='flex-end')))
Exemplo n.º 13
0
 def _class_path(self):
     ExprClass = self.__class__
     class_module = sys.modules[ExprClass.__module__]
     if hasattr(class_module, '__file__'):
         context = Context(class_module.__file__)
     else:
         context = Context(
         )  # use the current directory if using the main module
     # get the full class path relative to the root context where the class is defined
     class_path = context.name + '.' + ExprClass.__module__.split(
         '.')[-1] + '.' + ExprClass.__name__
     return class_path
Exemplo n.º 14
0
 def clear(self, kind):
     # context based upon current working directory
     self.context = Context()
     if kind == 'axioms':
         self.context._clearAxioms()
     elif kind == 'theorems':
         self.context._clearTheorems()
     elif kind == 'common':
         self.context._clearCommonExressions()
     elif KnownTruth.theoremBeingProven is not None:
         kind = '_proof_' + KnownTruth.theoremBeingProven.name
     # clean unreferenced expressions:
     self.context.referenceDisplayedExpressions(kind, clear=True)
     self.context.clean()
     self.kind = None
Exemplo n.º 15
0
 def subContextNotebook(self, subContextName):
     '''
     Returns the path of the _context_.ipynb notebook for the given sub-context,
     creating it if necessary.
     '''
     import proveit
     import json
     notebook_name = os.path.join(subContextName, '_context_.ipynb')
     if not os.path.isdir(subContextName):
         os.mkdir(subContextName)
         init_name = os.path.join(subContextName, '__init__.py')
         open(init_name, 'w')
     if os.path.isfile(notebook_name):
         # already exists
         return notebook_name
     proveit_path = os.path.split(proveit.__file__)[0]
     with open(os.path.join(proveit_path, '..', '_context_template_.ipynb'),
               'r') as template:
         nb = template.read()
         super_context_links = Context('.').links(
             from_directory=subContextName)
         nb = nb.replace('#CONTEXT#',
                         super_context_links + '.' + subContextName)
     # write the notebook file
     with open(notebook_name, 'w') as notebook_file:
         notebook_file.write(nb)
     return notebook_name
Exemplo n.º 16
0
 def display_context(self):
     '''
     Create the _common_, _axioms_ and _theorems_ notebooks for the current
     context (if they do not already exist).  Show the table of contents
     for sub-contexts which may be edited.
     '''
     import proveit
     # create an '__init__.py' in the directory if there is not an existing one.
     if not os.path.isfile('__init__.py'):
         open('__init__.py', 'w').close() # create an empty __init__.py
     context = Context()
     proveit_path = os.path.split(proveit.__file__)[0]
     special_notebook_types = ('common', 'axioms', 'theorems', 'demonstrations')
     special_notebook_texts = ('common expressions', 'axioms', 'theorems', 'demonstrations')
     for special_notebook_type in special_notebook_types:
         notebook_name = '_%s_.ipynb'%special_notebook_type
         if not os.path.isfile(notebook_name):
             # notebook does not yet exist, create it from the template
             template_name = '_%s_template_.ipynb'%special_notebook_type
             with open(os.path.join(proveit_path, '..', template_name), 'r') as template:
                 nb = template.read()
                 nb = nb.replace('#CONTEXT#', context.name)
             # write the notebook file
             with open(notebook_name, 'w') as notebook_file:
                 notebook_file.write(nb)
                 
     context_interface = ContextInterface()
     
     if context_interface.mode == 'static':
         special_notebooks_html = '<table><tr>\n'
         for special_notebook_type, special_notebook_text in zip(special_notebook_types, special_notebook_texts):
             special_notebooks_html += '<th><a class="ProveItLink" href="_%s_.ipynb">%s</a></th>\n'%(special_notebook_type, special_notebook_text)
         special_notebooks_html += '</tr></table>\n'
         if len(context_interface.subContextNames) > 0:
             special_notebooks_html += '<table>\n'
             for name in context_interface.subContextNames:
                 description = context_interface.subContextDescriptions[name]
                 href = context_interface.subContextNotebook(name)
                 special_notebooks_html += '<tr><th><a class="ProveItLink" href="%s">%s</a></th><td>%s</td></tr>\n'%(href, name, description)
             special_notebooks_html += '</table>\n'                
         display(HTML(special_notebooks_html))
     else:
         special_notebook_links = []
         full_width_layout = widgets.Layout(width='100%', padding='5px')
         for special_notebook_type, special_notebook_text in zip(special_notebook_types, special_notebook_texts):
             special_notebook_links.append(widgets.HTML('<a class="ProveItLink" href="_%s_.ipynb">%s</a>'%(special_notebook_type, special_notebook_text), layout=full_width_layout))
         special_notebook_links = widgets.HBox(special_notebook_links)
             
         sub_contexts_label = widgets.Label('List of sub-contexts:', layout = widgets.Layout(width='100%'))
         #sub_context_widgets = widgets.VBox(sub_context_widgets)
         add_context_widget = widgets.Text(value='', placeholder='Add sub-context...')
         def addSubContext(sender):
             context_interface.addSubContext(add_context_widget.value)
             add_context_widget.value = ''
         add_context_widget.on_submit(addSubContext)
         #layout = widgets.Layout(display='flex', flex_flow='column-reverse')
         #display(widgets.Button(description='Edit...', disabled=False, button_style='', tooltip='Edit the sub-contents list', layout=layout))
         #layout = widgets.Layout(float='bottom')
         display(widgets.VBox([special_notebook_links, sub_contexts_label, context_interface.widget, add_context_widget]))       
Exemplo n.º 17
0
 def check_expr(self, line):
     _, hash_id = os.path.split(os.path.abspath('.'))
     context = Context()
     expr_name = line.strip()
     if expr_name == '': 
         expr_name = 'expr'
         expr = self.shell.user_ns[expr_name]
     else:
         expr = self.shell.user_ns[expr_name]
         if isinstance(expr, KnownTruth):
             # actually a KnownTruth; convert to an Expression
             expr = expr.expr
     stored_expr = context.getStoredExpr(hash_id)
     if expr != stored_expr:
         raise ProveItMagicFailure("The built '%s' does not match the stored Expression"%expr_name)
     if expr._style_id != stored_expr._style_id:
         raise ProveItMagicFailure("The built '%s' style does not match that of the stored Expression"%expr_name)
     print "Passed sanity check: built '%s' is the same as the stored Expression."%expr_name
Exemplo n.º 18
0
 def _generate_unique_rep(self, objectRepFn, includeStyle=False):
     '''
     Generate a unique representation string using the given function to obtain representations of other referenced Prove-It objects.
     '''
     import sys
     context = Context(sys.modules[self.__class__.__module__].__file__)
     # get the full class path relative to the root context where the class is defined
     class_path = context.name + '.' + self.__class__.__module__.split('.')[-1] + '.' + self.__class__.__name__
     style_str = ''
     if includeStyle:
         style_str = ';[' + ','.join(style_name + ':' + self.getStyle(style_name) for style_name in sorted(self.styleNames())) + ']'
     return class_path + '[' + ','.join(self._coreInfo) + ']' + style_str + ';[' + ','.join(objectRepFn(expr) for expr in self._subExpressions) + ']'
Exemplo n.º 19
0
 def display_contents(self, context_names):
     '''
     Generates a "table of contents" hierarchy of contexts for the contexts
     listed in the line.
     '''
     def generateContents(contexts):
         if len(contexts)==0: return ''
         html = '<ul>\n'        
         for context in contexts:
             href = relurl(os.path.join(context.getPath(), '_context_.ipynb'))
             html += '<li><a class="ProveItLink" href="%s">%s</a></li>\n'%(href, context.name)
             html += generateContents(list(context.getSubContexts()))
         return html + '</ul>\n'
     display(HTML(generateContents([Context(context_name) for context_name in context_names])))
Exemplo n.º 20
0
import sys
from proveit._core_.context import Context, Axioms
sys.modules[__name__] = Axioms(Context(__file__))
Exemplo n.º 21
0
class ContextInterface:
    '''
    A SubContexts object is an interface for the _sub_contexts_.txt file
    which stores the names of the sub-contexts of the context in the current
    directory and also tracks whether it is in interactive or state mode.
    With each %context execution (in the _context_.ipynb notebook), the
    mode is toggled.  If in interactive mode, the SUbContexts object is
    responsible for creating the interactive widget to add/modify/remove
    sub-contexts and edit their brief descriptions.
    '''
    def __init__(self):
        self.context = Context()  # context of the current working directory
        self.subContextNames = list(self.context.getSubContextNames())
        self.subContextDescriptions = dict()

        # read the previous 'mode' (interactive or static) and toggle it.
        prev_mode = 'static'  # default toggles 'static' to 'interactive'
        if os.path.isfile('_mode_.txt'):
            with open('_mode_.txt', 'rt') as f:
                prev_mode = f.read().strip()
        # mode toggles between 'static' and 'interactive'
        if prev_mode == 'static':
            self.mode = 'interactive'
            # in interactive mode, sub-contexts are presented in an interactive widget
            self.widget = widgets.VBox()
            self.smallButtonLayout = widgets.Layout(width='30px')
            self.subContextLinkLayout = widgets.Layout(width='20%')
            self.subContextDescriptionLayout = widgets.Layout(width='80%')
        else:
            self.mode = 'static'

        # write the new mode that has been toggled
        with open('_mode_.txt', 'w') as f:
            f.write(self.mode + '\n')

        # register each sub-context name, reading their brief descriptions and
        # creating widgets if in interactive mode
        for sub_context_name in self.subContextNames:
            self._addSubContextRow(sub_context_name)

    def _addSubContextRow(self, subContextName):
        subContextDescription = self.readDescription(subContextName)
        self.subContextDescriptions[subContextName] = subContextDescription
        if self.mode == 'interactive':
            small_button_layout = self.smallButtonLayout
            sub_context_link_layout = self.subContextLinkLayout
            sub_context_description_layout = self.subContextDescriptionLayout
            #rename_button =  widgets.Button(description='', disabled=False, button_style='', tooltip='rename', icon='pencil', layout=small_button_layout)
            up_button = widgets.Button(description='',
                                       disabled=False,
                                       button_style='',
                                       tooltip='move up',
                                       icon='chevron-up',
                                       layout=small_button_layout)
            dn_button = widgets.Button(description='',
                                       disabled=False,
                                       button_style='',
                                       tooltip='move down',
                                       icon='chevron-down',
                                       layout=small_button_layout)
            delete_button = widgets.Button(description='',
                                           disabled=False,
                                           button_style='danger',
                                           tooltip='delete context',
                                           icon='trash',
                                           layout=small_button_layout)
            href = self.subContextNotebook(subContextName)
            sub_context_link = widgets.HTML(
                '<a class="ProveItLink" href="%s">%s</a>' %
                (href, subContextName),
                layout=sub_context_link_layout)
            sub_context_description = widgets.Text(
                value=subContextDescription,
                placeholder='Add a brief description here...',
                layout=sub_context_description_layout)

            def setDescription(change):
                self.subContextDescriptions[subContextName] = change['new']
                self.writeDescriptionFile(subContextName)

            sub_context_description.observe(setDescription, names='value')
            row_widget = widgets.VBox([
                widgets.HBox([
                    sub_context_link, sub_context_description, up_button,
                    dn_button, delete_button
                ])
            ])
            self.widget.children = self.widget.children + (row_widget, )

            def moveUp(sender):
                idx = self.subContextNames.index(subContextName)
                self.moveUp(idx)

            def moveDown(sender):
                idx = self.subContextNames.index(subContextName)
                self.moveUp(idx + 1)

            def deleteSubContext(sender):
                # before deleting a sub-context, we need confirmation by entering the sub-context name
                delete_msg = widgets.Label(
                    "To remove (unlink) sub-context, enter its name as confirmation",
                    layout={
                        'width': '400px',
                        'max_width': '400px'
                    })
                verification_text = widgets.Text(
                    layout=widgets.Layout(flex_grow=2, max_width='500px'))
                cancel_button = widgets.Button(description='cancel',
                                               disabled=False,
                                               tooltip='cancel',
                                               layout={'width': '80px'})
                cancel_button.on_click(dismissDelete)
                verification_text.observe(monitorConfirmation)
                row_widget.children = (
                    row_widget.children[0],
                    widgets.HBox(
                        [delete_msg, verification_text, cancel_button],
                        layout={'justify_content': 'flex-end'}))

            def dismissDelete(sender):
                # dismiss the delete confirmation/message by removing all be the first row in the row_widget
                row_widget.children = (row_widget.children[0], )

            def monitorConfirmation(change):
                # check to see if the user has entered the sub-context name for confirmation
                if change['new'] == subContextName:
                    # delete context has been
                    self.deleteSubContext(subContextName)

            up_button.on_click(moveUp)
            dn_button.on_click(moveDown)
            delete_button.on_click(deleteSubContext)

    def subContextNotebook(self, subContextName):
        '''
        Returns the path of the _context_.ipynb notebook for the given sub-context,
        creating it if necessary.
        '''
        import proveit
        import json
        notebook_name = os.path.join(subContextName, '_context_.ipynb')
        if not os.path.isdir(subContextName):
            os.mkdir(subContextName)
            init_name = os.path.join(subContextName, '__init__.py')
            open(init_name, 'w')
        if os.path.isfile(notebook_name):
            # already exists
            return notebook_name
        proveit_path = os.path.split(proveit.__file__)[0]
        with open(os.path.join(proveit_path, '..', '_context_template_.ipynb'),
                  'r') as template:
            nb = template.read()
            super_context_links = Context('.').links(
                from_directory=subContextName)
            nb = nb.replace('#CONTEXT#',
                            super_context_links + '.' + subContextName)
        # write the notebook file
        with open(notebook_name, 'w') as notebook_file:
            notebook_file.write(nb)
        return notebook_name

    def addSubContext(self, subContextName):
        '''
        Add a new sub-context with the given name.
        '''
        if subContextName in self.subContextNames:
            return
        if subContextName == '': return
        self.context.appendSubContextName(subContextName)
        self.subContextNames.append(subContextName)
        self._addSubContextRow(subContextName)

    def deleteSubContext(self, contextNameToDelete):
        '''
        Delete (unlink) a sub-context with the given name as long as there are not external
        references to its expressions.  Either way, the directory will remain.
        Only files in the __pv_it directories are cleared (recursively in all sub-sub contexts,
        etc) and the current directory's context will no longer link to it.  That is
        why we use the term 'unlinked'.  It may be resurrected by adding the sub-context
        with the same name back in.
        '''
        context = Context(contextNameToDelete)
        # remove all internal references and see if any external references remain
        context.clearAll()
        contains_expressions = context.containsAnyExpression()

        def dismiss(sender):
            if not contains_expressions:
                # Successful removal; we need to remove the deleted sub-context name from
                # the self.subContextNames list, the displayed widgets, and the list in _sub_contexts_.txt.
                new_sub_contexts = []
                new_widget_children = []
                for k, sub_context_name in enumerate(self.subContextNames):
                    if sub_context_name != contextNameToDelete:
                        new_sub_contexts.append(sub_context_name)
                        new_widget_children.append(self.widget.children[k])
                self.subContextNames = new_sub_contexts
                self.updateSubContextNames()
                self.widget.children = new_widget_children
            else:
                # dismiss the delete confirmation/message by removing all but the first row in the row_widget
                row_widget.children = (row_widget.children[0], )

        if not contains_expressions:
            msg = 'Removing (unlinking) sub-context; add it again to resurrect it or delete the directory to make it permanent'
            msg_width = '650px'
        else:
            msg = "Context removal cancelled; there are external references to its expressions (or corrupted '__pv_it' directories)"
            msg_width = '650px'
        row_widget = self.widget.children[self.subContextNames.index(
            contextNameToDelete)]
        delete_msg = widgets.Label(msg,
                                   layout={
                                       'width': msg_width,
                                       'max_width': msg_width
                                   })
        gotit_button = widgets.Button(description='got it',
                                      disabled=False,
                                      tooltip='got it',
                                      layout={'width': '80px'})
        gotit_button.on_click(dismiss)
        row_widget.children = (row_widget.children[0],
                               widgets.HBox([delete_msg, gotit_button],
                                            layout=widgets.Layout(
                                                justify_content='flex-end')))

    def moveUp(self, i):
        if i <= 0 or i == len(self.widget.children):
            return  # can't move the first entry up or go beyond the last entry
        self.widget.children = self.widget.children[:i - 1] + (
            self.widget.children[i],
            self.widget.children[i - 1]) + self.widget.children[i + 1:]
        self.subContextNames = self.subContextNames[:i - 1] + [
            self.subContextNames[i], self.subContextNames[i - 1]
        ] + self.subContextNames[i + 1:]
        self.updateSubContextNames()

    def readDescription(self, subContextName):
        brief_description = ''
        brief_description_filename = os.path.join(subContextName,
                                                  '_brief_description_.txt')
        if os.path.isfile(brief_description_filename):
            with open(brief_description_filename) as f2:
                brief_description = f2.read().strip()
        self.subContextDescriptions[subContextName] = brief_description
        return brief_description

    def writeDescriptionFile(self, subContextName):
        brief_description = self.subContextDescriptions[subContextName]
        if brief_description != '':
            brief_description_filename = os.path.join(
                subContextName, '_brief_description_.txt')
            with open(brief_description_filename, 'w') as f:
                f.write(brief_description + '\n')

    def updateSubContextNames(self):
        '''
        Update the stored sub-context names (in the _sub_contexts_.txt file) with
        self.subContextNames
        '''
        # rewrite the sub_contexts.txt file with new information.
        self.context.setSubContextNames(self.subContextNames)
Exemplo n.º 22
0
 def show_proof(self):
     _, hash_id = os.path.split(os.path.abspath('.'))
     context = Context()
     return context.getShowProof(hash_id)
Exemplo n.º 23
0
class ProveItMagic(Magics):
    "Magics that hold additional state"

    def __init__(self, shell, assignmentBehaviorModifier):
        # You must call the parent constructor
        super(ProveItMagic, self).__init__(shell)
        self.kind = None
        self.definitions = dict()
        self.keys = []  # the keys of the definitions in the order they appear
        self.lowerCaseNames = set()
        self.context = None
        self.ranFinish = False
        self.assignmentBehaviorModifier = assignmentBehaviorModifier
        assignmentBehaviorModifier.displayAssignments(ip)

    @line_magic
    def display_assignments(self, line):
        if line.strip() == 'off':
            self.assignmentBehaviorModifier.resetBehavior()
        else:
            self.assignmentBehaviorModifier.displayAssignments(self.shell)

    @line_magic
    def context(self, line):
        '''
        Create the _common_, _axioms_ and _theorems_ notebooks for the current
        context (if they do not already exist).  Show the table of contents
        for sub-contexts which may be edited.
        '''
        import proveit
        import ipywidgets as widgets
        # create an '_init_.py' in the directory if there is not an existing one.
        if not os.path.isfile('__init__.py'):
            open('__init__.py', 'w').close()  # create an empty __init__.py
        context = Context()
        proveit_path = os.path.split(proveit.__file__)[0]
        special_notebook_types = ('common', 'axioms', 'theorems',
                                  'demonstrations')
        special_notebook_texts = ('common expressions', 'axioms', 'theorems',
                                  'demonstrations')
        for special_notebook_type in special_notebook_types:
            notebook_name = '_%s_.ipynb' % special_notebook_type
            if not os.path.isfile(notebook_name):
                # notebook does not yet exist, create it from the template
                template_name = '_%s_template_.ipynb' % special_notebook_type
                with open(os.path.join(proveit_path, '..', template_name),
                          'r') as template:
                    nb = template.read()
                    nb = nb.replace('#CONTEXT#', context.name)
                # write the notebook file
                with open(notebook_name, 'w') as notebook_file:
                    notebook_file.write(nb)

        context_interface = ContextInterface()

        if context_interface.mode == 'static':
            special_notebooks_html = '<table>\n'
            for special_notebook_type, special_notebook_text in zip(
                    special_notebook_types, special_notebook_texts):
                special_notebooks_html += '<th><a class="ProveItLink" href="_%s_.ipynb">%s</a></th>\n' % (
                    special_notebook_type, special_notebook_text)
            special_notebooks_html += '</table>\n'
            if len(context_interface.subContextNames) > 0:
                special_notebooks_html += '<table>\n'
                for name in context_interface.subContextNames:
                    description = context_interface.subContextDescriptions[
                        name]
                    href = context_interface.subContextNotebook(name)
                    special_notebooks_html += '<tr><th><a class="ProveItLink" href="%s">%s</a></th><td>%s</td></tr>\n' % (
                        href, name, description)
                special_notebooks_html += '</table>\n'
            display(HTML(special_notebooks_html))
        else:
            special_notebook_links = []
            full_width_layout = widgets.Layout(width='100%', padding='5px')
            for special_notebook_type, special_notebook_text in zip(
                    special_notebook_types, special_notebook_texts):
                special_notebook_links.append(
                    widgets.HTML(
                        '<a class="ProveItLink" href="_%s_.ipynb">%s</a>' %
                        (special_notebook_type, special_notebook_text),
                        layout=full_width_layout))
            special_notebook_links = widgets.HBox(special_notebook_links)

            sub_contexts_label = widgets.Label(
                'List of sub-contexts:', layout=widgets.Layout(width='100%'))
            #sub_context_widgets = widgets.VBox(sub_context_widgets)
            add_context_widget = widgets.Text(value='',
                                              placeholder='Add sub-context...')

            def addSubContext(sender):
                context_interface.addSubContext(add_context_widget.value)
                add_context_widget.value = ''

            add_context_widget.on_submit(addSubContext)
            #layout = widgets.Layout(display='flex', flex_flow='column-reverse')
            #display(widgets.Button(description='Edit...', disabled=False, button_style='', tooltip='Edit the sub-contents list', layout=layout))
            #layout = widgets.Layout(float='bottom')
            display(
                widgets.VBox([
                    special_notebook_links, sub_contexts_label,
                    context_interface.widget, add_context_widget
                ]))

    def begin_axioms(self):
        # context based upon current working directory
        self.context = Context()
        if len(self.definitions) > 0 or self.kind is not None:
            if self.kind != 'axioms':
                raise ProveItMagicFailure(
                    "Run %%begin_axioms in a separate notebook from %%begin_%s."
                    % self.kind)
            print "WARNING: Re-running %begin_axioms does not reset previously defined axioms."
            print "         It is suggested that you restart and run all cells after editing axioms."
        print "Defining axioms for context '" + self.context.name + "'"
        print "Subsequent end-of-cell assignments will define axioms"
        print "%end_axioms will finalize the definitions"

    def end_axioms(self):
        self._finish('axioms')

    def begin_theorems(self):
        # context based upon current working directory
        if len(self.definitions) > 0 or self.kind is not None:
            if self.kind != 'theorems':
                raise ProveItMagicFailure(
                    "Run %%begin_theorems in a separate notebook from %%begin_%s."
                    % self.kind)
            print "WARNING: Re-running %begin_theorems does not reset previously defined theorems."
            print "         It is suggested that you restart and run all cells after editing theorems."
        print "Defining theorems for context '" + self.context.name + "'"
        print "Subsequent end-of-cell assignments will define theorems"
        print "'%end theorems' will finalize the definitions"

    def end_theorems(self):
        self._finish('theorems')
        # stash proof notebooks that are not active theorems.
        self.context.stashExtraneousProofNotebooks()

    def begin_common(self):
        if len(self.definitions) > 0 or self.kind is not None:
            if self.kind != 'common':
                raise ProveItMagicFailure(
                    "Run '%%begin common' in a separate notebook from %%begin_%s."
                    % self.kind)
            print "WARNING: Re-running '%begin common' does not reset previously defined common expressions."
            print "         It is suggested that you restart and run all cells after editing the expressions."
        print "Defining common sub-expressions for context '" + self.context.name + "'"
        print "Subsequent end-of-cell assignments will define common sub-expressions"
        print "%end_common will finalize the definitions"

    def end_common(self):
        # Record the context names of common expressions referenced
        # by this context's common expressions notebook...
        self.context.recordCommonExprDependencies()
        # and check for illegal mutual references.
        cyclically_referenced_common_expr_context = self.context.cyclicallyReferencedCommonExprContext(
        )
        if cyclically_referenced_common_expr_context is not None:
            raise ProveItMagicFailure(
                "Not allowed to have cyclically dependent 'common expression' notebooks: %s._common_"
                % cyclically_referenced_common_expr_context)
        self._finish('common')

    @line_magic
    def begin(self, line):
        kind = line.strip()
        # context based upon current working directory
        self.context = Context()
        if kind == 'axioms':
            self.begin_axioms()
        elif kind == 'theorems':
            self.begin_theorems()
        elif kind == 'common':
            self.begin_common()
        self.kind = kind

    @line_magic
    def end(self, line):
        kind = line.strip()
        if kind == 'axioms':
            self.end_axioms()
        elif kind == 'theorems':
            self.end_theorems()
        elif kind == 'common':
            self.end_common()
        # reference any expressions that were displayed:
        self.context.referenceDisplayedExpressions(kind)
        # clean unreferenced expressions:
        self.context.clean()
        self.kind = None

    @line_magic
    def clear(self, line):
        kind = line.strip()
        # context based upon current working directory
        self.context = Context()
        if kind == 'axioms':
            self.context._clearAxioms()
        elif kind == 'theorems':
            self.context._clearTheorems()
        elif kind == 'common':
            self.context._clearCommonExressions()
        elif KnownTruth.theoremBeingProven is not None:
            kind = '_proof_' + KnownTruth.theoremBeingProven.name
        # clean unreferenced expressions:
        self.context.referenceDisplayedExpressions(kind, clear=True)
        self.context.clean()
        self.kind = None

    @line_magic
    def check_expr(self, line):
        _, hash_id = os.path.split(os.path.abspath('.'))
        context = Context()
        expr_name = line.strip()
        if expr_name == '':
            expr_name = 'expr'
            expr = self.shell.user_ns[expr_name]
        else:
            expr = self.shell.user_ns[expr_name]
            if isinstance(expr, KnownTruth):
                # actually a KnownTruth; convert to an Expression
                expr = expr.expr
        stored_expr = context.getStoredExpr(hash_id)
        if expr != stored_expr:
            raise ProveItMagicFailure(
                "The built '%s' does not match the stored Expression" %
                expr_name)
        if expr._style_id != stored_expr._style_id:
            raise ProveItMagicFailure(
                "The built '%s' style does not match that of the stored Expression"
                % expr_name)
        print "Passed sanity check: built '%s' is the same as the stored Expression." % expr_name

    @line_magic
    def proving(self, line):
        from proveit._core_.proof import Theorem
        self.context = Context(
            '..'
        )  # the context should be up a directory from the _proofs_ directory
        sys.path.append('..')
        theorem_name, presuming_str = str(line.strip()).split(' ', 1)
        if not presuming_str.find('presuming ') == 0:
            print "Format: %begin_proof <theorem_name> presuming [<list of theorems / context-names>]"
            return
        args = presuming_str.split(' ', 1)[-1].strip('[]').split(',')
        theorem_truth = Context('..').getTheorem(theorem_name).provenTruth
        print "Beginning proof of", theorem_name
        presuming = [arg.strip() for arg in args if arg.strip() != '']
        # The list of theorems/context-names may be composed of full-path strings containing '.'s
        # or may be actual theorem variables defined in the IPython sesson.  The latter
        # instances will be converted to strings.
        for k, arg in enumerate(list(presuming)):
            if '.' not in arg:
                knownTruth = self.shell.user_ns[arg]
                if not isinstance(knownTruth, KnownTruth) or not isinstance(
                        knownTruth.proof(), Theorem):
                    raise ValueError(
                        "Presuming list must be composed of full-path theorem/context-name containing '.'s or be KnownTruth variable representing a Theorem"
                    )
                theorem = knownTruth.proof()
                presuming[k] = str(theorem)  # full path of theorem
        begin_proof_result = theorem_truth.beginProof(presuming)
        if isinstance(begin_proof_result, Expression):
            # assign the theorem name to the theorem expression
            # and display this assignment
            theorem_expr = theorem_truth.expr
            self.shell.user_ns[theorem_name] = theorem_expr
            return Assignments([theorem_name], [theorem_expr],
                               beginningProof=True)

    @line_magic
    def qed(self, line):
        proof = KnownTruth.theoremBeingProven.provenTruth._qed()
        proof._repr_html_()  # generate expressions that should be referenced
        self.context.referenceDisplayedExpressions(
            '_proof_' + KnownTruth.theoremBeingProven.name)
        # clean unreferenced expressions:
        self.context.clean()
        return proof

    def _finish(self, kind):
        '''
        Finish 'axioms', 'theorems', or 'common' for the Context
        associated with the current working directory.
        '''
        if self.kind != kind:
            raise ProveItMagicFailure(r"Must run %begin " + kind +
                                      r" before %end " + kind)
        # Add the special statements / expressions to the context
        context = self.context
        if kind == 'axioms':
            context._setAxioms(self.keys, self.definitions)
        elif kind == 'theorems':
            context._setTheorems(self.keys, self.definitions)
        elif kind == 'common':
            context._setCommonExpressions(self.keys, self.definitions)

        # Make a _common_.py, _axioms_.py or _theorems_.py for importing
        # expressions from the certified database.
        context.makeSpecialExprModule(kind)

        # Update the expression notebooks now that these have been registered
        # as special expressions.
        for name, expr in self.definitions.iteritems():
            # remake the expression notebooks using the special expressions of the context
            context.expressionNotebook(expr)

        if len(self.definitions) == 0:
            print "Context %s has no %s" % (context.name, kind if kind !=
                                            'common' else 'common expressions')
        elif kind == 'common':
            print "Common expressions may be imported from autogenerated _%s_.py" % kind
        else:
            print "%s may be imported from autogenerated _%s_.py" % (
                (kind[0].upper() + kind[1:]), kind)
        self.ranFinish = True

    @line_magic
    def dependencies(self, line):
        '''
        Show the dependencies of an axiom or theorem.
        '''
        from .proof import Theorem
        name = line.strip()
        known_truth = self.shell.user_ns[line.strip()]
        proof = known_truth.proof()  # Axiom or Theorem

        def displaySpecialStmt(stmt):
            '''
            Given an Axiom or Theorem, display HTML with a link
            to the definition.
            '''
            expr = stmt.provenTruth.expr
            display(
                HTML(
                    '<dt><a class="ProveItLink" href="%s">%s</a></dt><dd>%s</dd>'
                    % (stmt.getLink(), str(stmt), expr._repr_html_())))

        def stmt_sort(stmt):
            return str(stmt)

        if isinstance(proof, Theorem):
            try:
                required_axioms, required_unproven_theorems = proof.allRequirements(
                )
            except:
                display(HTML('<h3>This theorem has not been proven yet.</h3>'))
                required_axioms, required_unproven_theorems = tuple(), tuple()

            if len(required_unproven_theorems) > 0:
                display(
                    HTML(
                        '<h3>Unproven theorems required (directly or indirectly) to prove %s</h3>'
                        % name))
                display(HTML('<dl>'))
                for required_unproven_theorem in sorted(
                        required_unproven_theorems, key=stmt_sort):
                    displaySpecialStmt(
                        Context.findTheorem(required_unproven_theorem))
                display(HTML('</dl>'))
            if len(required_axioms) > 0:
                display(
                    HTML(
                        '<h3>Axioms required (directly or indirectly) to prove %s</h3>'
                        % name))
                display(HTML('<dl>'))
                for required_axiom in sorted(required_axioms, key=stmt_sort):
                    displaySpecialStmt(Context.findAxiom(required_axiom))
                display(HTML('</dl>'))

        dependents = proof.directDependents()
        if len(dependents) == 0:
            display(HTML('<h3>No theorems depend upon %s</h3>' % name))
        else:
            display(HTML('<h3>Theorems that depend directly on %s</h3>' %
                         name))
            display(HTML('<dl>'))
            for dependent in sorted(proof.directDependents(), key=stmt_sort):
                displaySpecialStmt(Context.findTheorem(dependent))
            display(HTML('</dl>'))
Exemplo n.º 24
0
class ProveItMagicCommands:
    def __init__(self):
        self.reset()

    def reset(self):
        # You must call the parent constructor
        self.kind = None
        self.definitions = dict()  # map name to expression
        self.expr_names = dict()  # map expression to names
        self.keys = []  # the keys of the definitions in the order they appear
        self.lowerCaseNames = set()
        self.context = None
        self.ranFinish = False

    def display_contents(self, context_names):
        '''
        Generates a "table of contents" hierarchy of contexts for the contexts
        listed in the line.
        '''
        def generateContents(contexts):
            if len(contexts) == 0: return ''
            html = '<ul>\n'
            for context in contexts:
                href = relurl(
                    os.path.join(context.getPath(), '_context_.ipynb'))
                html += '<li><a class="ProveItLink" href="%s">%s</a></li>\n' % (
                    href, context.name)
                html += generateContents(list(context.getSubContexts()))
            return html + '</ul>\n'

        display(
            HTML(
                generateContents([
                    Context(context_name) for context_name in context_names
                ])))

    def display_context(self):
        '''
        Create the _common_, _axioms_ and _theorems_ notebooks for the current
        context (if they do not already exist).  Show the table of contents
        for sub-contexts which may be edited.
        '''
        import proveit
        # create an '__init__.py' in the directory if there is not an existing one.
        if not os.path.isfile('__init__.py'):
            open('__init__.py', 'w').close()  # create an empty __init__.py
        context = Context()
        proveit_path = os.path.split(proveit.__file__)[0]
        special_notebook_types = ('common', 'axioms', 'theorems',
                                  'demonstrations')
        special_notebook_texts = ('common expressions', 'axioms', 'theorems',
                                  'demonstrations')
        for special_notebook_type in special_notebook_types:
            notebook_name = '_%s_.ipynb' % special_notebook_type
            if not os.path.isfile(notebook_name):
                # notebook does not yet exist, create it from the template
                template_name = '_%s_template_.ipynb' % special_notebook_type
                with open(os.path.join(proveit_path, '..', template_name),
                          'r') as template:
                    nb = template.read()
                    nb = nb.replace('#CONTEXT#', context.name)
                # write the notebook file
                with open(notebook_name, 'w') as notebook_file:
                    notebook_file.write(nb)

        context_interface = ContextInterface()

        if context_interface.mode == 'static':
            special_notebooks_html = '<table><tr>\n'
            for special_notebook_type, special_notebook_text in zip(
                    special_notebook_types, special_notebook_texts):
                special_notebooks_html += '<th><a class="ProveItLink" href="_%s_.ipynb">%s</a></th>\n' % (
                    special_notebook_type, special_notebook_text)
            special_notebooks_html += '</tr></table>\n'
            if len(context_interface.subContextNames) > 0:
                special_notebooks_html += '<table>\n'
                for name in context_interface.subContextNames:
                    description = context_interface.subContextDescriptions[
                        name]
                    href = context_interface.subContextNotebook(name)
                    special_notebooks_html += '<tr><th><a class="ProveItLink" href="%s">%s</a></th><td>%s</td></tr>\n' % (
                        href, name, description)
                special_notebooks_html += '</table>\n'
            display(HTML(special_notebooks_html))
        else:
            special_notebook_links = []
            full_width_layout = widgets.Layout(width='100%', padding='5px')
            for special_notebook_type, special_notebook_text in zip(
                    special_notebook_types, special_notebook_texts):
                special_notebook_links.append(
                    widgets.HTML(
                        '<a class="ProveItLink" href="_%s_.ipynb">%s</a>' %
                        (special_notebook_type, special_notebook_text),
                        layout=full_width_layout))
            special_notebook_links = widgets.HBox(special_notebook_links)

            sub_contexts_label = widgets.Label(
                'List of sub-contexts:', layout=widgets.Layout(width='100%'))
            #sub_context_widgets = widgets.VBox(sub_context_widgets)
            add_context_widget = widgets.Text(value='',
                                              placeholder='Add sub-context...')

            def addSubContext(sender):
                context_interface.addSubContext(add_context_widget.value)
                add_context_widget.value = ''

            add_context_widget.on_submit(addSubContext)
            #layout = widgets.Layout(display='flex', flex_flow='column-reverse')
            #display(widgets.Button(description='Edit...', disabled=False, button_style='', tooltip='Edit the sub-contents list', layout=layout))
            #layout = widgets.Layout(float='bottom')
            display(
                widgets.VBox([
                    special_notebook_links, sub_contexts_label,
                    context_interface.widget, add_context_widget
                ]))

    def begin_axioms(self):
        # context based upon current working directory
        self.context = Context()
        if len(self.definitions) > 0 or self.kind is not None:
            if self.kind != 'axioms':
                raise ProveItMagicFailure(
                    "Run %%begin_axioms in a separate notebook from %%begin_%s."
                    % self.kind)
            print(
                "WARNING: Re-running %begin_axioms does not reset previously defined axioms."
            )
            print(
                "         It is suggested that you restart and run all cells after editing axioms."
            )
        print("Defining axioms for context '" + self.context.name + "'")
        print("Subsequent end-of-cell assignments will define axioms")
        print("%end_axioms will finalize the definitions")

    def begin_theorems(self):
        # context based upon current working directory
        if len(self.definitions) > 0 or self.kind is not None:
            if self.kind != 'theorems':
                raise ProveItMagicFailure(
                    "Run %%begin_theorems in a separate notebook from %%begin_%s."
                    % self.kind)
            print(
                "WARNING: Re-running %begin_theorems does not reset previously defined theorems."
            )
            print(
                "         It is suggested that you restart and run all cells after editing theorems."
            )
        print("Defining theorems for context '" + self.context.name + "'")
        print("Subsequent end-of-cell assignments will define theorems")
        print("'%end theorems' will finalize the definitions")

    def begin_common(self):
        if len(self.definitions) > 0 or self.kind is not None:
            if self.kind != 'common':
                raise ProveItMagicFailure(
                    "Run '%%begin common' in a separate notebook from %%begin_%s."
                    % self.kind)
            print(
                "WARNING: Re-running '%begin common' does not reset previously defined common expressions."
            )
            print(
                "         It is suggested that you restart and run all cells after editing the expressions."
            )
        print("Defining common sub-expressions for context '" +
              self.context.name + "'")
        print(
            "Subsequent end-of-cell assignments will define common sub-expressions"
        )
        print("%end_common will finalize the definitions")

    def clear(self, kind):
        # context based upon current working directory
        self.context = Context()
        if kind == 'axioms':
            self.context._clearAxioms()
        elif kind == 'theorems':
            self.context._clearTheorems()
        elif kind == 'common':
            self.context._clearCommonExressions()
        elif KnownTruth.theoremBeingProven is not None:
            kind = '_proof_' + KnownTruth.theoremBeingProven.name
        # clean unreferenced expressions:
        self.context.referenceDisplayedExpressions(kind, clear=True)
        self.context.clean()
        self.kind = None

    def check_expr(self, expr_name, expr):
        _, hash_id = os.path.split(os.path.abspath('.'))
        context = Context()
        stored_expr = context.getStoredExpr(hash_id)
        if expr != stored_expr:
            raise ProveItMagicFailure(
                "The built '%s' does not match the stored Expression" %
                expr_name)
        if expr._style_id != stored_expr._style_id:
            raise ProveItMagicFailure(
                "The built '%s' style does not match that of the stored Expression"
                % expr_name)
        print(
            "Passed sanity check: built '%s' is the same as the stored Expression."
            % expr_name)

    def proving(self,
                theorem_name,
                presumptions,
                justRecordPresumingInfo=False):
        self.context = Context(
            '..'
        )  # the context should be up a directory from the _proofs_ directory
        sys.path.append('..')
        proving_theorem = self.context.getTheorem(theorem_name)
        proving_theorem_truth = proving_theorem.provenTruth
        print("Beginning proof of", theorem_name)
        return proving_theorem_truth.beginProof(
            proving_theorem,
            presumptions,
            justRecordPresumingInfo=justRecordPresumingInfo)

    def qed(self):
        proof = KnownTruth.theoremBeingProven.provenTruth._qed()
        proof._repr_html_()  # generate expressions that should be referenced
        self.context.referenceDisplayedExpressions(
            '_proof_' + KnownTruth.theoremBeingProven.name)
        # clean unreferenced expressions:
        self.context.clean()
        return proof

    def end(self, kind):
        '''
        Finish 'axioms', 'theorems', 'common', or other (e.g., 'demonstrations')
        for the Context associated with the current working directory.
        '''
        if self.kind != kind:
            raise ProveItMagicFailure(r"Must run %begin " + kind +
                                      r" before %end " + kind)
        # Add the special statements / expressions to the context
        context = self.context
        if kind == 'axioms':
            context._setAxioms(self.keys, self.definitions)
        elif kind == 'theorems':
            context._setTheorems(self.keys, self.definitions)
        elif kind == 'common':
            # Record the context names of common expressions referenced
            # by this context's common expressions notebook...
            context.recordCommonExprDependencies()
            # and check for illegal mutual references.
            cyclically_referenced_common_expr_context = self.context.cyclicallyReferencedCommonExprContext(
            )
            if cyclically_referenced_common_expr_context is not None:
                raise ProveItMagicFailure(
                    "Not allowed to have cyclically dependent 'common expression' notebooks: %s._common_"
                    % cyclically_referenced_common_expr_context)
            context._setCommonExpressions(self.keys, self.definitions)

        if kind in ('axioms', 'theorems', 'common'):
            # Make a _common_.py, _axioms_.py or _theorems_.py for importing
            # expressions from the certified database.
            context.makeSpecialExprModule(kind)

            # Update the expression notebooks now that these have been registered
            # as special expressions.
            for name, expr in self.definitions.items():
                # remake the expression notebooks using the special expressions of the context
                context.expressionNotebook(expr)

            if len(self.definitions) == 0:
                print("Context %s has no %s" %
                      (context.name,
                       kind if kind != 'common' else 'common expressions'))
            elif kind == 'common':
                print(
                    "Common expressions may be imported from autogenerated _%s_.py"
                    % kind)
            else:
                print("%s may be imported from autogenerated _%s_.py" %
                      ((kind[0].upper() + kind[1:]), kind))
        self.ranFinish = True

        # reference any expressions that were displayed:
        self.context.referenceDisplayedExpressions(kind)
        # clean unreferenced expressions:
        self.context.clean()
        if kind == 'theorems':
            # stash proof notebooks that are not active theorems.
            self.context.stashExtraneousProofNotebooks()
        self.kind = None

    def display_dependencies(self, name, known_truth):
        '''
        Show the dependencies of an axiom or theorem.
        '''
        proof = known_truth.proof()  # Axiom or Theorem

        def displaySpecialStmt(stmt):
            '''
            Given an Axiom or Theorem, display HTML with a link
            to the definition.
            '''
            expr = stmt.provenTruth.expr
            display(
                HTML(
                    '<dt><a class="ProveItLink" href="%s">%s</a></dt><dd>%s</dd>'
                    % (stmt.getLink(), str(stmt), expr._repr_html_())))

        def stmt_sort(stmt):
            return str(stmt)

        if isinstance(proof, Theorem):
            try:
                required_axioms, required_unproven_theorems = proof.allRequirements(
                )
            except:
                display(HTML('<h3>This theorem has not been proven yet.</h3>'))
                required_axioms, required_unproven_theorems = tuple(), tuple()

            if len(required_unproven_theorems) > 0:
                display(
                    HTML(
                        '<h3>Unproven theorems required (directly or indirectly) to prove %s</h3>'
                        % name))
                display(HTML('<dl>'))
                for required_unproven_theorem in sorted(
                        required_unproven_theorems, key=stmt_sort):
                    displaySpecialStmt(
                        Context.findTheorem(required_unproven_theorem))
                display(HTML('</dl>'))
            if len(required_axioms) > 0:
                display(
                    HTML(
                        '<h3>Axioms required (directly or indirectly) to prove %s</h3>'
                        % name))
                display(HTML('<dl>'))
                for required_axiom in sorted(required_axioms, key=stmt_sort):
                    displaySpecialStmt(Context.findAxiom(required_axiom))
                display(HTML('</dl>'))

        dependents = proof.directDependents()
        if len(dependents) == 0:
            display(HTML('<h3>No theorems depend upon %s</h3>' % name))
        else:
            display(HTML('<h3>Theorems that depend directly on %s</h3>' %
                         name))
            display(HTML('<dl>'))
            for dependent in sorted(proof.directDependents(), key=stmt_sort):
                displaySpecialStmt(Context.findTheorem(dependent))
            display(HTML('</dl>'))
Exemplo n.º 25
0
    def _make(literalClass, coreInfo, styles, subExpressions):
        '''
        Make the object of class `literalClass` matching the core information
        and sub expressions.
        '''
        from proveit import Context
        import inspect
        if len(subExpressions) > 0:
            raise ValueError('Not expecting any subExpressions of Literal')
        if len(coreInfo) < 4:
            raise ValueError("Expecting " + literalClass.__name__ +
                             " coreInfo to contain at least 4 items: '" +
                             literalClass.__name__ +
                             "', stringFormat, latexFormat, and the context")
        if coreInfo[0] != 'Literal':
            raise ValueError("Expecting coreInfo[0] to be 'Literal'")
        coreInfo = tuple(coreInfo)  # make it hashable
        if coreInfo in Literal.instances:
            return Literal.instances[coreInfo].withStyles(**styles)
        else:
            # If the Literal is not in the instances dictionary, just make it independently
            # without storing it in the instances dictionary.  This allows us to create
            # Expression objects out of the __pv_it database without causing
            # a DuplicateLiteralError.
            string_format, latex_format = coreInfo[1:3]
            context = Context.getContext(coreInfo[3])
            prev_context_default = Context.default
            Context.default = context
            try:
                extra_core_info = coreInfo[4:]
                init_args = inspect.getargspec(literalClass.__init__)[0]
                if literalClass == Literal:
                    made_obj = Literal(string_format, latex_format,
                                       extra_core_info, context)
                elif len(init_args) == 1:
                    made_obj = literalClass(
                    )  # no arguments (except self) are taken
                elif len(init_args) == 2 and init_args[
                        1] == 'stringFormat' and coreInfo[1] == coreInfo[2]:
                    made_obj = literalClass(string_format, context)
                elif len(init_args) == 3 and init_args[
                        1] == 'stringFormat' and init_args[2] == 'latexFormat':
                    made_obj = literalClass(string_format, latex_format)
                elif len(init_args) == 4 and init_args[
                        1] == 'stringFormat' and init_args[
                            2] == 'latexFormat' and init_args[3] == 'context':
                    made_obj = literalClass(string_format, latex_format,
                                            context)
                elif hasattr(literalClass, 'makeLiteral'):
                    if len(extra_core_info) == 0:
                        made_obj = literalClass.makeLiteral(
                            string_format, latex_format, context)
                    else:
                        made_obj = literalClass.makeLiteral(
                            string_format, latex_format, extra_core_info,
                            context)
                else:
                    raise NotImplementedError(
                        "Must implement the 'makeLiteral(string_format, latex_format, context)' static method for class %s"
                        % str(literalClass))
            finally:
                Context.default = prev_context_default  # restore the default

            Literal.instances.pop(coreInfo)
            return made_obj.withStyles(**styles)
Exemplo n.º 26
0
import sys
from proveit._core_.context import Context, Theorems
sys.modules[__name__] = Theorems(Context(__file__))