• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
      • Break-rewrite
      • Proof-builder
      • Accumulated-persistence
      • Cgen
      • Forward-chaining-reports
      • Proof-tree
      • Print-gv
      • Dmr
      • With-brr-data
      • Splitter
      • Guard-debug
      • Set-debugger-enable
      • Redo-flat
      • Time-tracker
      • Set-check-invariant-risk
      • Removable-runes
      • Efficiency
      • Explain-near-miss
        • Tail-biting
        • Failed-forcing
        • Sneaky
        • Invariant-risk
        • Failure
        • Measure-debug
        • Dead-events
        • Compare-objects
        • Prettygoals
        • Remove-hyps
        • Type-prescription-debugging
        • Pstack
        • Trace
        • Set-register-invariant-risk
        • Walkabout
        • Disassemble$
        • Nil-goal
        • Cw-gstack
        • Set-guard-msg
        • Find-lemmas
        • Watch
        • Quick-and-dirty-subsumption-replacement-step
        • Profile-all
        • Profile-ACL2
        • Set-print-gv-defaults
        • Minimal-runes
        • Spacewalk
        • Try-gl-concls
        • Near-misses
      • Std
      • Proof-automation
      • Macro-libraries
      • ACL2
        • Theories
        • Rule-classes
        • Proof-builder
        • Recursion-and-induction
        • Hons-and-memoization
        • Events
        • Parallelism
        • History
        • Programming
        • Operational-semantics
        • Real
        • Start-here
        • Debugging
          • Break-rewrite
          • Proof-builder
          • Accumulated-persistence
          • Cgen
          • Forward-chaining-reports
          • Proof-tree
          • Print-gv
          • Dmr
          • With-brr-data
          • Splitter
          • Guard-debug
          • Set-debugger-enable
          • Redo-flat
          • Time-tracker
          • Set-check-invariant-risk
          • Removable-runes
          • Efficiency
          • Explain-near-miss
            • Tail-biting
            • Failed-forcing
            • Sneaky
            • Invariant-risk
            • Failure
            • Measure-debug
            • Dead-events
            • Compare-objects
            • Prettygoals
            • Remove-hyps
            • Type-prescription-debugging
            • Pstack
            • Trace
            • Set-register-invariant-risk
            • Walkabout
            • Disassemble$
            • Nil-goal
            • Cw-gstack
            • Set-guard-msg
            • Find-lemmas
            • Watch
            • Quick-and-dirty-subsumption-replacement-step
            • Profile-all
            • Profile-ACL2
            • Set-print-gv-defaults
            • Minimal-runes
            • Spacewalk
            • Try-gl-concls
            • Near-misses
          • Miscellaneous
          • Output-controls
          • Macros
          • Interfacing-tools
        • Interfacing-tools
        • Hardware-verification
        • Software-verification
        • Math
        • Testing-utilities
      • Debugging

      Explain-near-miss

      show why a rule's pattern and the :target do not match

      When a near miss break occurs (see monitor) the user sees a message like this:

      (1 Breaking (:REWRITE LEMMA) on (F (G A B) A '(A B C D ...)):
      
      The pattern in this rule failed to match the target.  However, this
      is considered a NEAR MISS under the break criteria,
      (:CONDITION 'T :ABSTRACTION ...), specified when this rule was
      monitored.  The following criterion is satisfied.
      
      * The :ABSTRACTION pattern provided in your monitor, ...,
      matches :TARGET.

      It can be difficult to determine why the pattern of the rule, e.g., the :lhs of a :rewrite rule, fails to match the :target term, especially when large terms, large quoted constants, and lambda expressions are involved.

      Included among the :brr-commands is the :explain-near-miss command which is intended to help explain. This command can only operate in a near miss break. If called in another context an error may occur.

      But in a near miss break, the situation is as follows. The prover has tried to apply a rule that has been monitored with a break criterion meaning ``cause an interactive break when the target term (the term to currently being rewritten) satisfies this criterion but the triggering pattern of the rule fails to match the target term.'' When inside the resulting break, the target term is given by the brr command :target. The ``triggering pattern'' of the rule in question depends on how the rule was stored (see rule-classes). The triggering pattern of a :rewrite rule — the most common class of rule — is the left-hand side of the concluding equality and can be obtained from within the break by typing the brr command :lhs. The triggering pattern for a :rewrite-quoted-constant rule is its right-hand side, but as explained in rewrite-quoted-constant, the brr command :lhs will display it. The triggering pattern for a :linear rule is displayed by the :max-term brr command. The question the user will typically ask in this situation is ``why doesn't the triggering pattern match the target?''

      To understand the answer you have to understand how the ACL2 matching algorithm works. The matching algorithm is given two terms, t1 and t2, and attempts to find a substitution s on the variables in t1 such that when t1 is instantiated with s the result is t2, i.e., t1/s = t2. Note that only the variables in the pattern, t1, can be instantiated by s'. In the case of a near miss break, no such substitution was found.

      The :explain-near-miss command reruns the matching algorithm on the triggering pattern and the target, expecting failure and collecting information about where the failure occurred. The output is intended to be self-explanatory.

      The message displays the pattern in question and the target term, but it also displays a version of the pattern in which the first unmatchable subterm is replaced by the expression <pat>. That <pat> is displayed in lowercase whereas the rest of the pattern and target are in uppercase. It marks where the matching broke down.

      The message goes on to show the mismatched subterms from the pattern and the target, the substitution that was computed to match everything up to <pat> and what the <pat> subterm of the pattern is when instantiated with that substitution.

      So, for example, suppose the rule's :lhs and the current :target are as shown below. Then here is what :explain-near-miss would print.

      The ACL2 match algorithm attempted to match :LHS with :TARGET by finding
      a substitution, s, such that :LHS/s = :TARGET.  That attempt failed
      when trying to match the subterm of :LHS marked <pat> in :LHS' below.
      
      :LHS:      (F X (G X Y) (H X))
      :LHS':     (F X (G <pat> Y) (H X))
      :TARGET:   (F A (G B A) (H A))
      
      Below we show the substitution, s, computed prior to the failure; the
      subterm of :LHS we're calling <pat>; the instantiated subterm, <pat>/s;
      and the corresponding subterm, <tar>, of :TARGET.
      
      s:       ((X A))
      <pat>:   X
      <pat>/s: A
      <tar>:   B
      
      For the rewriter to get past this failure the match algorithm must
      be able to extend substitution s to s' so that <pat>/s' is equal to
      <tar> and our match algorithm could not find such an extension.

      Note that the substitution s binds X to A to match the first argument of the F-expression in the :LHS to the corresponding argument in the :TARGET. Then it tries to match (G X Y) with (G B A). It fails on the first argument of that subterm, where <pat> is shown in :LHS', because X has been bound to A and A and B are different. (Remember: only the variables of the pattern can be bound by the substitution.)

      When <pat> and its corresponding subterm <tar> are ``large'' but unequal quoted constants or lambda expressions, :explain-near-miss will call compare-objects on those objects. It can be hard to spot how two large constants differ and compare-objects points out the differences between two cons trees. :Explain-near-miss considers an object ``large'' if the number of conses in it is 30 or greater.

      The command :explain-near-miss+ is like :explain-near-miss except it never eviscerates any term and runs compare-objects whenever the failure is on two distinct quoted objects or lambda expressions regardless of their sizes.

      But note that compare-objects is not run by either version of explain-near-miss when the failure is of the most common kinds:

      • (a) a variable in the pattern has already been bound in the substitution (i.e., bound earlier in the matching process) to a term that is not identical to the corresponding term in the target, or
      • (b) a term in the pattern has a different function symbol than the corresponding term the target.

      So do not expect the compare-objects output to appear often!