summaryrefslogtreecommitdiff
path: root/books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp')
-rw-r--r--books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp2780
1 files changed, 2780 insertions, 0 deletions
diff --git a/books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp b/books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp
new file mode 100644
index 0000000..f01e2cb
--- /dev/null
+++ b/books/workshops/2003/ray-matthews-tuttle/support/bisimilarity.lisp
@@ -0,0 +1,2780 @@
+(in-package "ACL2")
+
+;; The following two lines are added for portability to v2-7.
+
+
+#|
+
+ bisimilarity.lisp
+ ~~~~~~~~~~~~~~~~~
+
+We take a step back now, and define the concepts of bisimilarity inside
+ACL2. The text-book definition of bisimilarity is as follows. A relation B
+between states of two Kripke Structures m and n is a bisimilarity relation if
+for every initial state of m there is an initial state in n such that B holds,
+and for every pair of states in which B holds, there is a next state for which
+B holds. Two models are said to be bisimulation equivalent if such a relation
+exists between the two models.
+
+The theory of bisimulation, frankly, is a higher order theory and, ACL2 (my
+apologies to Matt and J) cannot deal with it. However, we do what feeble
+efforts we can possibly master, and try to do as much work as possible with the
+encapsulations in ACL2. However, I strongly believe that treatment like this in
+ACL2 is nothing more than a hack.
+
+As an afterthought, we implement bisimilarity here, with respect to a given
+collection of variables. What this means is that two states will be called
+bisimilar if they have the same value for the given set of variables in the
+label, and for every next state of these states, the next states are bisimilar
+wrt the same set of variables. This is useful for reduction algorithms for
+model-checking that we are interested in, and will let us do away with
+hand-waving statements of the form that two states are bisimilar with labelling
+restricted to C.
+
+|#
+
+;; Since we do not want to see ACL2 reduce mv-nth 0 to car etc. we do the
+;; following tricks. I should ask Matt to have these as macro's or as a syntaxp
+;; hypothesis and disable mv-nth.
+
+(defthm mv-nth-0-reduce
+ (equal (mv-nth 0 (mv x y z)) x))
+
+(defthm mv-nth-1-reduce
+ (equal (mv-nth 1 (mv x y z)) y))
+
+(defthm mv-nth-2-reduce
+ (equal (mv-nth 2 (mv x y z)) z))
+
+(in-theory (disable mv-nth)) ;; We do not need to disable mv since mv is a
+ ;; macro.
+
+;; End of macros for mv-nth.
+
+;; The book ltl is included here since I will use the Kripke Structures there
+;; to define my bisimilarity.
+
+(include-book "ltl")
+
+;; These two rules are found to be expensive, which is obvious given what these
+;; rules are. I disable them here and in cone-of-influence.lisp and the proof
+;; is much much faster.
+
+(in-theory (disable subset-of-empty-is-empty
+ subset-of-nil-is-nil))
+
+;; Now we encapsulate the property of bisimilarity for two states. Briefly, two
+;; states are bisimilar if they have labels equal within vars, and for every
+;; next state of one, there exists a next state of another that is bisimilar.
+
+(encapsulate
+ (((bisimilar * * * * *) => *)
+ ((bisimilar-transition-witness-m->n * * * * * *) => *)
+ ((bisimilar-initial-state-witness-m->n * * * *) => *)
+ ((bisimilar-transition-witness-n->m * * * * * *) => *)
+ ((bisimilar-initial-state-witness-n->m * * * *) => *)
+ ((bisimilar-equiv * * *) => *))
+
+ (local
+ (defun bisimilar (p m q n vars)
+ (declare (ignore vars))
+ (and (equal p q)
+ (equal m n)))
+ )
+
+ (local
+ (defun bisimilar-transition-witness-m->n (p r m q n vars)
+ (declare (ignore p m q n vars))
+ r)
+ )
+
+ (local
+ (defun bisimilar-initial-state-witness-m->n (s m n vars)
+ (declare (ignore m n vars))
+ s)
+ )
+
+
+ (local
+ (defun bisimilar-transition-witness-n->m (p m q r n vars)
+ (declare (ignore p m q n vars))
+ r)
+ )
+
+ (local
+ (defun bisimilar-initial-state-witness-n->m (m s n vars)
+ (declare (ignore m n vars))
+ s)
+ )
+
+ (local
+ (defun bisimilar-equiv (m n vars)
+ (declare (ignore vars))
+ (equal m n))
+ )
+
+
+ ;; If two Kripke Structures m and n are equivalent with respect to a bisimilar
+ ;; relation B, then for every initial-state of m there is a initial-state of n
+ ;; that is bisimilar.
+
+ (defthm bisimilar-equiv-implies-init->init-m->n
+ (implies (and (bisimilar-equiv m n vars)
+ (memberp s (initial-states m)))
+ (memberp (bisimilar-initial-state-witness-m->n s m n vars)
+ (initial-states n))))
+
+ (defthm bisimilar-equiv-implies-bisimilar-initial-states-m->n
+ (implies (and (bisimilar-equiv m n vars)
+ (memberp s (initial-states m)))
+ (bisimilar s m
+ (bisimilar-initial-state-witness-m->n s m n vars)
+ n vars)))
+
+ ;; And the same result holds for n to m
+
+ (defthm bisimilar-equiv-implies-init->init-n->m
+ (implies (and (bisimilar-equiv m n vars)
+ (memberp s (initial-states n)))
+ (memberp (bisimilar-initial-state-witness-n->m m s n vars)
+ (initial-states m))))
+
+ (defthm bisimilar-equiv-implies-bisimilar-initial-states-n->m
+ (implies (and (bisimilar-equiv m n vars)
+ (memberp s (initial-states n)))
+ (bisimilar (bisimilar-initial-state-witness-n->m m s n vars)
+ m s n vars)))
+
+ ;; Bisimilar states have the same label with respect to vars. I just use
+ ;; set-equality because they might not have "equal" labels. BTW, I might not
+ ;; need the modelp hypothesis here. But I plug it in, just so that I can keep
+ ;; the (functional instance of) bisimilarity relation as simple as possible.
+
+ (defthm bisimilar-states-have-labels-equal
+ (implies (and (bisimilar p m q n vars)
+ (modelp m)
+ (modelp n))
+ (set-equal (set-intersect (label-of p m) vars)
+ (set-intersect (label-of q n) vars))))
+
+
+
+ ;; Of course bisimilarity witness is a member of states of the corresponding model.
+
+ (defthm bisimilar-witness-member-of-states-m->n
+ (implies (and (bisimilar p m q n vars)
+ (next-statep p r m)
+ (memberp r (states m)))
+ (memberp (bisimilar-transition-witness-m->n p r m q n vars)
+ (states n))))
+
+ ;; Again this part may not be required.
+
+ (defthm bisimilar-witness-member-of-states-n->m
+ (implies (and (bisimilar p m q n vars)
+ (next-statep q r n)
+ (memberp r (states n)))
+ (memberp (bisimilar-transition-witness-n->m p m q r n vars)
+ (states m))))
+
+ ;; And if two states are bisimilar, then for every next state of one, there is
+ ;; a next state of another which is bisimilar.
+
+ (defthm bisimilar-witness-matches-transition-m->n
+ (implies (and (bisimilar p m q n vars)
+ (next-statep p r m))
+ (next-statep q (bisimilar-transition-witness-m->n p r m q n vars)
+ n)))
+
+ (defthm bisimilar-witness-produces-bisimilar-states-m->n
+ (implies (and (bisimilar p m q n vars)
+ (next-statep p r m))
+ (bisimilar r m
+ (bisimilar-transition-witness-m->n p r m q n vars)
+ n vars)))
+
+ ;; Again this part may not be required.
+
+ (defthm bisimilar-witness-matches-transition-n->m
+ (implies (and (bisimilar p m q n vars)
+ (next-statep q r n))
+ (next-statep p (bisimilar-transition-witness-n->m p m q r n vars)
+ m)))
+
+
+
+ (defthm bisimilar-witness-produces-bisimilar-states-n->m
+ (implies (and (bisimilar p m q n vars)
+ (next-statep q r n))
+ (bisimilar (bisimilar-transition-witness-n->m p m q r n vars)
+ m r n vars)))
+
+)
+
+;; The next phase of the book is to show that if two Kripke Structures are
+;; bisim-equiv, then for each periodic path of one, there exists a periodic
+;; path of another that has the same labels within vars. This finally will show
+;; that for any LTL formula restricted to the variable set in vars, the
+;; evaluation of the formula wrt bisimilar structures is identical.
+
+
+;; In find-matching-path-for-path, we create a finite path in n that is
+;; bisimilar to a (finite) path in m.
+
+(defun find-matching-path-for-path-m->n (path m q n vars)
+ (cond ((endp path) nil)
+ ((endp (rest path)) (list q))
+ (t (cons q (find-matching-path-for-path-m->n
+ (rest path) m
+ (bisimilar-transition-witness-m->n
+ (first path) (second path) m q n vars)
+ n vars)))))
+
+;; And a similar function from n to m. This is really unfortunate. We could
+;; have gotten rid of this duplication if we could rely on symmetry. But I want
+;; the encapsulation to provide me with as little constraint as possible.
+
+(defun find-matching-path-for-path-n->m (p m path n vars)
+ (cond ((endp path) nil)
+ ((endp (rest path)) (list p))
+ (t (cons p (find-matching-path-for-path-n->m
+ (bisimilar-transition-witness-n->m
+ p m (first path) (second path) n vars)
+ m (rest path)
+ n vars)))))
+
+
+;; The function to handle periodic paths is rather complicated, and needs to be
+;; decomposed. Here is our solution.
+
+(defun snoc (x e)
+ (if (endp x) (list e)
+ (cons (first x) (snoc (rest x) e))))
+
+(defun del-last (x)
+ (if (endp x) nil
+ (if (endp (rest x)) nil
+ (cons (first x) (del-last (rest x))))))
+
+(defthm del-last-snoc-reduction
+ (implies (true-listp x)
+ (equal (del-last (snoc x e)) x)))
+
+
+(defun find-prefix (cycle seen witness path)
+ (cond ((endp path) nil)
+ ((endp seen) path) ;; should not arise
+ ((equal witness (first seen)) nil)
+ (t (append (first-n (len cycle) path) (find-prefix
+ cycle (rest seen) witness
+ (last-n (len cycle) path))))))
+
+(defun find-cycle (cycle seen witness path)
+ (cond ((endp seen) nil) ;; should not arise
+ ((endp path) nil)
+ ((equal witness (first seen)) path)
+ (t (find-cycle cycle (rest seen) witness (last-n (len cycle) path)))))
+
+;; ACL2 is really stupid in arithmetic. I just add Robert's collection of
+;; arithmetic books to get it thru with what I want. I need arithmetic really for
+;; very weird reasons, but well, what the heck, I dont want to deal with
+;; arithmetic myself any ways.
+
+(local
+(include-book "../../../../arithmetic-2/meta/top")
+)
+
+(local
+(defthm len-of-snoc-is-more
+ (< (len x) (len (snoc x e)))
+ :rule-classes :linear)
+)
+
+;; The following function determines a weird path in n, when given a cycle in
+;; m. The weird path is a finite path compatible with n, and can be thought of
+;; as the append of the prefix and cycle.
+
+(defun find-matching-prefix-and-cycle-for-cycle-m->n (cycle m seen q states n vars path)
+ (declare (xargs :measure (nfix (- (1+ (len states)) (len seen)))))
+ ;; for termination using Pigeon-hole arguments
+ (if (< (len states) (len seen)) (mv seen q path)
+ (let* ((path-produced (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ (node-witness (bisimilar-transition-witness-m->n
+ (last-val cycle) (first cycle) m
+ (last-val path-produced) n vars)))
+ (if (memberp node-witness seen)
+ (mv (snoc seen node-witness) node-witness (append path path-produced))
+ (find-matching-prefix-and-cycle-for-cycle-m->n cycle m (snoc seen node-witness)
+ node-witness states n
+ vars (append path
+ path-produced))))))
+
+(defun find-matching-prefix-and-cycle-for-cycle-n->m (seen q states m cycle n vars path)
+ (declare (xargs :measure (nfix (- (1+ (len states)) (len seen)))))
+ ;; for termination using Pigeon-hole arguments
+ (if (< (len states) (len seen)) (mv seen q path)
+ (let* ((path-produced (find-matching-path-for-path-n->m
+ q m cycle n vars))
+ (node-witness (bisimilar-transition-witness-n->m
+ (last-val path-produced) m
+ (last-val cycle) (first cycle) n vars)))
+ (if (memberp node-witness seen)
+ (mv (snoc seen node-witness) node-witness (append path path-produced))
+ (find-matching-prefix-and-cycle-for-cycle-n->m (snoc seen node-witness)
+ node-witness states m
+ cycle n
+ vars (append path
+ path-produced))))))
+
+
+;; And we pick up the prefix from the weird path
+
+(defun find-matching-prefix-for-cycle-m->n (cycle m q n vars)
+ (mv-let (seen witness path)
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil)
+ (find-prefix cycle (del-last seen) witness path)))
+
+(defun find-matching-prefix-for-cycle-n->m (q m cycle n vars)
+ (mv-let (seen witness path)
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars nil)
+ (find-prefix cycle (del-last seen) witness path)))
+
+
+;; and also the cycle.
+
+(defun find-matching-cycle-for-cycle-m->n (cycle m q n vars)
+ (mv-let (seen witness path)
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil)
+ (find-cycle cycle (del-last seen) witness path)))
+
+(defun find-matching-cycle-for-cycle-n->m (q m cycle n vars)
+ (mv-let (seen witness path)
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars nil)
+ (find-cycle cycle (del-last seen) witness path)))
+
+;; So we can now produce the matching periodic path by appending the prefix
+;; after the matching path for the prefix and the cycle as we obtained.
+
+(defun find-matching-periodic-path-m->n (ppath m n vars)
+ (let* ((init-p (initial-state ppath))
+ (prefix-p (prefix ppath))
+ (first-p (first prefix-p))
+ (cycle-p (cycle ppath))
+ (init-q (bisimilar-initial-state-witness-m->n init-p m n vars))
+ (first-q (bisimilar-transition-witness-m->n init-p first-p m init-q n
+ vars))
+ (match-path (find-matching-path-for-path-m->n prefix-p m first-q n
+ vars))
+ (last-p (last-val prefix-p))
+ (last-q (last-val match-path))
+ (first-cp (first cycle-p))
+ (first-cq (bisimilar-transition-witness-m->n last-p first-cp m last-q
+ n vars))
+ (match-prefix (find-matching-prefix-for-cycle-m->n
+ cycle-p m first-cq n vars))
+ (match-cycle (find-matching-cycle-for-cycle-m->n
+ cycle-p m first-cq n vars)))
+ (>_ :initial-state init-q
+ :prefix (append match-path match-prefix)
+ :cycle match-cycle)))
+
+(defun find-matching-periodic-path-n->m (m ppath n vars)
+ (let* ((init-q (initial-state ppath))
+ (prefix-q (prefix ppath))
+ (first-q (first prefix-q))
+ (cycle-q (cycle ppath))
+ (init-p (bisimilar-initial-state-witness-n->m m init-q n vars))
+ (first-p (bisimilar-transition-witness-n->m init-p m init-q first-q n
+ vars))
+ (match-path (find-matching-path-for-path-n->m first-p m prefix-q n
+ vars))
+ (last-q (last-val prefix-q))
+ (last-p (last-val match-path))
+ (first-cq (first cycle-q))
+ (first-cp (bisimilar-transition-witness-n->m last-p m last-q first-cq
+ n vars))
+ (match-prefix (find-matching-prefix-for-cycle-n->m
+ first-cp m cycle-q n vars))
+ (match-cycle (find-matching-cycle-for-cycle-n->m
+ first-cp m cycle-q n vars)))
+ (>_ :initial-state init-p
+ :prefix (append match-path match-prefix)
+ :cycle match-cycle)))
+
+
+;; Now we bite the bullet and start showing that this dirty bad function suits
+;; our purpose. Any suggestions for improvement will be greatly appreciated.
+
+;; Let us define the general concept of what we mean by two paths (or segments
+;; being bisimilar.
+
+
+(local
+(defun bisimilar-segments-p (p m q n vars)
+ (if (endp p) (endp q)
+ (and (consp q)
+ (bisimilar (first p) m (first q) n vars)
+ (bisimilar-segments-p (rest p) m (rest q) n vars))))
+)
+
+;; And of course we can then define when a sequence of segments appended
+;; together is bisimilar.
+
+
+(local
+(defun bisimilar-segments-sequence-p (p m q n vars)
+ (declare (xargs :measure (len q)))
+ (if (endp q) T
+ (if (or (endp p) (< (len q) (len p))) nil
+ (and (bisimilar-segments-p p m (first-n (len p) q) n vars)
+ (bisimilar-segments-sequence-p p m (last-n (len p) q) n vars)))))
+)
+
+(local
+(defun bisimilar-segments-sequence-p-2 (p m q n vars)
+ (declare (xargs :measure (len p)))
+ (if (endp p) T
+ (if (or (endp q) (< (len p) (len q))) nil
+ (and (bisimilar-segments-p (first-n (len q) p) m q n vars)
+ (bisimilar-segments-sequence-p-2 (last-n (len q) p) m q n vars)))))
+)
+
+
+;; Of course now, we know that find-matching-path produces a bisimilar path.
+
+(local
+(defthm find-matching-path-produces-bisimilar-segments
+ (implies (and (compatible-path-p p m)
+ (bisimilar (first p) m q n vars))
+ (bisimilar-segments-p
+ p m
+ (find-matching-path-for-path-m->n p m q n vars)
+ n vars)))
+)
+
+(local
+(defthm find-matching-path-produces-bisimilar-segments-2
+ (implies (and (compatible-path-p q n)
+ (bisimilar p m (first q) n vars))
+ (bisimilar-segments-p
+ (find-matching-path-for-path-n->m p m q n vars)
+ m q
+ n vars)))
+)
+
+;; and bisimilar paths have the same length.
+
+(local
+(defthm bisimilar-to-length
+ (implies (bisimilar-segments-p p m q n vars)
+ (equal (len p) (len q)))
+ :rule-classes :forward-chaining)
+)
+
+(local
+(defthm len-of-append
+ (equal (len (append x y))
+ (+ (len x) (len y))))
+)
+
+(local
+(defthm last-n-is-true-listp
+ (implies (true-listp p)
+ (true-listp (last-n i p))))
+)
+
+(local
+(defthm first-last-append-reduction-2
+ (implies (<= i (len x))
+ (equal (append x y)
+ (append (first-n i x) (append (last-n i x) y)))))
+)
+
+(local
+(defthm first-n-reduced
+ (implies (and (equal (len x) i)
+ (true-listp x))
+ (equal (first-n i x) x)))
+)
+
+(local
+(defthm last-n-reduced
+ (implies (and (<= (len x) i)
+ (integerp i)
+ (true-listp x))
+ (equal (last-n i x) nil)))
+)
+
+;; and bisimilar segements would also be bisimilar-segments-sequence.
+
+(local
+(defthm bisimilar-segments-are-bisimilar-segment-sequences
+ (implies (and (bisimilar-segments-p p m q n vars)
+ (true-listp p)
+ (true-listp q)
+ (consp p))
+ (bisimilar-segments-sequence-p p m q n vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :induct (bisimilar-segments-sequence-p p m q n vars)
+ :do-not-induct t)))
+)
+
+(local
+(defthm bisimilar-segments-are-bisimilar-segment-sequences-2
+ (implies (and (bisimilar-segments-p p m q n vars)
+ (true-listp p)
+ (true-listp q)
+ (consp q))
+ (bisimilar-segments-sequence-p-2 p m q n vars))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :induct (bisimilar-segments-sequence-p-2 p m q n vars)
+ :do-not-induct t)))
+)
+
+;; which when appended will produce bisimilar segments sequence.
+
+(local
+(defthm append-of-bisimilar-segments-produces-bisimilar-segment-list
+ (implies (and (bisimilar-segments-p p m r n vars)
+ (consp p)
+ (true-listp r)
+ (true-listp p)
+ (true-listp q)
+ (bisimilar-segments-sequence-p p m q n vars))
+ (bisimilar-segments-sequence-p p m (append q r) n vars))
+ :hints (("Goal"
+ :do-not '(generalize eliminate-destructors)
+ :do-not-induct t
+ :induct (bisimilar-segments-sequence-p p m q n vars))))
+)
+
+(local
+(defthm append-of-bisimilar-segments-produces-bisimilar-segment-list-2
+ (implies (and (bisimilar-segments-p r m q n vars)
+ (consp q)
+ (true-listp r)
+ (true-listp p)
+ (true-listp q)
+ (bisimilar-segments-sequence-p-2 p m q n vars))
+ (bisimilar-segments-sequence-p-2 (append p r) m q n vars))
+ :hints (("Goal"
+ :do-not '(generalize eliminate-destructors)
+ :do-not-induct t
+ :induct (bisimilar-segments-sequence-p-2 p m q n vars))))
+)
+
+;; and the prefix of bisimilar segements sequence is a
+;; bisimialr-segments-sequence
+
+(local
+(defthm prefix-produces-bisimilar-segment-list
+ (implies (bisimilar-segments-sequence-p p m q n vars)
+ (bisimilar-segments-sequence-p p m (find-prefix p seen witness q) n
+ vars)))
+)
+
+(local
+(defthm prefix-produces-bisimilar-segment-list-2
+ (implies (bisimilar-segments-sequence-p-2 p m q n vars)
+ (bisimilar-segments-sequence-p-2 (find-prefix q seen witness p) m q n
+ vars)))
+
+)
+
+;; and so is the cycle.
+
+(local
+(defthm cycle-produces-bisimilar-segment-list
+ (implies (bisimilar-segments-sequence-p p m q n vars)
+ (bisimilar-segments-sequence-p p m (find-cycle p seen witness q) n
+ vars)))
+)
+
+(local
+(defthm cycle-produces-bisimilar-segment-list-2
+ (implies (bisimilar-segments-sequence-p-2 p m q n vars)
+ (bisimilar-segments-sequence-p-2 (find-cycle q seen witness p) m q n
+ vars)))
+)
+
+;; Also the last-vals of compatible paths is bisimilar.
+
+(local
+(defthm last-vals-are-bisimilar
+ (implies (and (compatible-path-p path m)
+ (consp path)
+ (bisimilar (first path) m q n vars))
+ (bisimilar (last-val path) m
+ (last-val (find-matching-path-for-path-m->n path m q n
+ vars))
+ n vars)))
+)
+
+(local
+(defthm last-vals-are-bisimilar-2
+ (implies (and (compatible-path-p path n)
+ (consp path)
+ (bisimilar p m (first path) n vars))
+ (bisimilar (last-val (find-matching-path-for-path-n->m p m path n
+ vars))
+ m (last-val path)
+ n vars)))
+)
+
+
+
+(local
+(defthm true-listp-append-reduction
+ (implies (true-listp y)
+ (true-listp (append x y))))
+)
+
+;; and therefore, finally, the segment produced by find-prefix-and-cycle is
+;; bisimilar segments sequence-p
+
+(local
+(defthm matching-prefix-and-cycle-produces-bisimilar-segment-list
+ (implies (and (consp cycle)
+ (true-listp path)
+ (bisimilar-segments-sequence-p cycle m path n vars)
+ (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars))
+ (bisimilar-segments-sequence-p
+ cycle m
+ (mv-nth
+ 2
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q
+ states n vars path))
+ n vars)))
+)
+
+(local
+(defthm matching-prefix-and-cycle-produces-bisimilar-segment-list-2
+ (implies (and (consp cycle)
+ (true-listp path)
+ (bisimilar-segments-sequence-p-2 path m cycle n vars)
+ (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars))
+ (bisimilar-segments-sequence-p-2
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))
+ m cycle
+ n vars))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n
+ vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+
+;; which means that the prefix is bisimilar segments sequence
+
+(local
+(defthm find-matching-prefix-is-bisimilar-segments-p
+ (implies (and (consp cycle)
+ (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (car cycle) m)
+ (bisimilar (first cycle) m q n vars))
+ (bisimilar-segments-sequence-p
+ cycle m (find-matching-prefix-for-cycle-m->n cycle m q n vars) n
+ vars)))
+)
+
+(local
+(defthm find-matching-prefix-is-bisimilar-segments-p-2
+ (implies (and (consp cycle)
+ (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (car cycle) n)
+ (bisimilar q m (first cycle) n vars))
+ (bisimilar-segments-sequence-p-2
+ (find-matching-prefix-for-cycle-n->m q m cycle n vars) m cycle n
+ vars)))
+)
+
+;; and so is the cycle.
+
+(local
+(defthm find-matching-cycle-is-bisimilar-segments-p
+ (implies (and (consp cycle)
+ (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (car cycle) m)
+ (bisimilar (first cycle) m q n vars))
+ (bisimilar-segments-sequence-p
+ cycle m (find-matching-cycle-for-cycle-m->n cycle m q n vars) n
+ vars)))
+
+)
+
+(local
+(defthm find-matching-cycle-is-bisimilar-segments-p-2
+ (implies (and (consp cycle)
+ (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (car cycle) n)
+ (bisimilar q m (first cycle) n vars))
+ (bisimilar-segments-sequence-p-2
+ (find-matching-cycle-for-cycle-n->m q m cycle n vars) m cycle n
+ vars)))
+
+)
+
+;; Now of course, a periodic path is bisimilar to another if the following
+;; holds.
+
+(local
+(defun bisimilar-periodic-paths-p (p m q n vars)
+ (and (bisimilar (initial-state p) m (initial-state q) n vars)
+ (or (and (bisimilar-segments-p (prefix p) m
+ (first-n (len (prefix p)) (prefix q))
+ n vars)
+ (bisimilar-segments-sequence-p
+ (cycle p) m
+ (last-n (len (prefix p)) (prefix q)) n vars)
+ (bisimilar-segments-sequence-p (cycle p) m (cycle q) n vars))
+ (and (bisimilar-segments-p (first-n (len (prefix q)) (prefix p)) m
+ (prefix q) n vars)
+ (bisimilar-segments-sequence-p-2 (last-n (len (prefix q))
+ (prefix p))
+ m (cycle q) n vars)
+ (bisimilar-segments-sequence-p-2
+ (cycle p) m (cycle q) n vars)))))
+
+)
+
+;; We need to show that find-matching-periodic-path-m->ns produce
+;; bisimilar-periodic-paths-p.
+
+
+;; And we need to append things the other way around to get it through.
+
+(local
+(in-theory (disable find-matching-prefix-for-cycle-m->n
+ find-matching-cycle-for-cycle-m->n
+ find-matching-prefix-for-cycle-n->m
+ find-matching-cycle-for-cycle-n->m))
+)
+
+(local
+(defthm find-matching-path-for-path-has-same-len
+ (equal (len (find-matching-path-for-path-m->n p m q n vars))
+ (len p)))
+)
+
+(local
+(defthm find-matching-path-for-path-has-same-len-2
+ (equal (len (find-matching-path-for-path-n->m p m q n vars))
+ (len q)))
+)
+
+(local
+(defthm find-matching-periodic-path-m->n-produces-bisimilar-periodic-paths
+ (implies (and (compatible-ppath-p ppath m)
+ (bisimilar-equiv m n vars))
+ (bisimilar-periodic-paths-p ppath m
+ (find-matching-periodic-path-m->n
+ ppath m n
+ vars)
+ n vars))
+ :hints (("Goal"
+ :do-not-induct t)))
+)
+
+(local
+(defthm find-matching-periodic-path-m->n-produces-bisimilar-periodic-paths-2
+ (implies (and (compatible-ppath-p ppath n)
+ (bisimilar-equiv m n vars))
+ (bisimilar-periodic-paths-p
+ (find-matching-periodic-path-n->m m ppath n
+ vars)
+ m ppath
+ n vars))
+ :hints (("Goal"
+ :do-not-induct t)))
+)
+
+;; Now let us prove that bisimilar periodic paths have labels equal.
+
+
+(local
+ (in-theory (disable set-equal set-intersect))
+ )
+
+(local
+(defthm bisimilar-segments-have-equal-labels
+ (implies (and (bisimilar-segments-p p m q n vars)
+ (modelp m)
+ (modelp n))
+ (equal-label-segments-p p m q n vars)))
+)
+
+(local
+(defthm bisimilar-segments-sequence-p-have-equal-labels
+ (implies (and (bisimilar-segments-sequence-p p m q n vars)
+ (modelp m)
+ (modelp n))
+ (equal-label-segments-sequence-p-small-p p m q n vars)))
+)
+
+(local
+(defthm bisimilar-segments-sequence-p-have-equal-labels-2
+ (implies (and (bisimilar-segments-sequence-p-2 p m q n vars)
+ (modelp m)
+ (modelp n))
+ (equal-label-segments-sequence-p-large-p p m q n vars)))
+)
+
+(local
+(defthm bisimilar-periodic-paths-have-equal-labels
+ (implies (and (bisimilar-periodic-paths-p p m q n vars)
+ (modelp m)
+ (modelp n))
+ (equal-labels-periodic-path-p p m q n vars)))
+)
+
+(local
+(in-theory (disable bisimilar-periodic-paths-p equal-labels-periodic-path-p))
+)
+
+(local
+(defthm ppath-and-its-matching-ppath-have-same-labels
+ (implies (and (compatible-ppath-p ppath m)
+ (bisimilar-equiv m n vars)
+ (modelp m)
+ (modelp n))
+ (equal-labels-periodic-path-p
+ ppath m (find-matching-periodic-path-m->n ppath m n vars) n vars))
+ :hints (("Goal"
+ :in-theory (disable compatible-ppath-p
+ find-matching-periodic-path-m->n))))
+
+)
+
+(local
+(defthm ppath-and-its-matching-ppath-have-same-labels-2
+ (implies (and (compatible-ppath-p ppath n)
+ (bisimilar-equiv m n vars)
+ (modelp m)
+ (modelp n))
+ (equal-labels-periodic-path-p
+ (find-matching-periodic-path-n->m m ppath n vars) m ppath n vars))
+ :hints (("Goal"
+ :in-theory (disable compatible-ppath-p
+ find-matching-periodic-path-n->m))))
+
+)
+
+
+;; OK let us now think over what I proved so far. Briefly I have proved that if
+;; P is a periodic path in m, and m and n are bisimilar-equivalent, then there
+;; is a periodic path which has the same labels. Now what do we need to
+;; prove? We need to prove that the periodic path we have proved to have the
+;; same label must be a path of n. That is it is compatible with n. If we do
+;; that, then we would know that for every path in m there is a path in n that
+;; has the same labels. hence we will know that ltl-semantics of m and n for a
+;; restricted formula f is same.
+
+
+;; Unfortunately, this property (though trivial intuitively) is not an easy
+;; property for a theorem-proving exercise. It needs a lot of work showing (for
+;; example) pigeon-hole principle. I will discuss the issues as we get
+;; there. For now, let us start proving each of the constraints of
+;; compatible-ppath-p separately. There is no real mystery here, --- I took a
+;; printout of ltl.lisp, and decided to prove each of the constraints
+;; separately.
+
+;; To prove these constraints separately, I will bear in mind that in the final
+;; theorem compatible-ppath-p is going to be enabled. This being a recursive
+;; function, we will have to be careful that in the lemmas, we do not have
+;; compatible-ppath-p as a hypothesis.
+
+;; The first theorem in our agenda is to show that initial-state of matching
+;; ppath is a member of initial states. That is obvious, from the constraints
+;; of bisimilar-initial-state-witness.
+
+
+;; The next theorem is to show that the prefix is a consp. This is because we
+;; start with a matching-path of a consp prefix and append of a consp with
+;; something is a consp. This is established by the next two theorems.
+
+(local
+(defthm prefix-is-a-consp
+ (equal (consp (find-matching-path-for-path-m->n path m q n vars))
+ (consp path)))
+)
+
+(local
+(defthm prefix-is-a-consp-2
+ (equal (consp (find-matching-path-for-path-n->m q m path n vars))
+ (consp path)))
+)
+
+
+(local
+(defthm append-expands-to-consp
+ (equal (consp (append x y))
+ (if (consp x) T (consp y))))
+)
+
+;; The next constraint says that the first of the prefix is next state of
+;; init. This is trivial from property of bisimilar-transition-witness and the
+;; fact that inits of the two models are bisimilar.
+
+
+
+;; The next constraint is to show that the cycle is a consp. In other words, we
+;; have to show the consp property for find-matching-cycle-for-cyle. Now why
+;; is the cycle consp. Roughly, the reason is as follows. The length of the
+;; path produced by prefix and cycle is (len seen) * (len cycle). And the
+;; witness is a member of path. seen. Hence the cycle produced is a consp by
+;; the next two theorems.
+
+(local
+(defthm last-n-len-reduction
+ (implies (and (equal (len path) (+ i j))
+ (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j))
+ (equal (len (last-n i path))
+ j)))
+)
+
+(local
+(defthm witness-member-of-seen-implies-consp
+ (implies (and (memberp witness seen)
+ (consp cycle)
+ (force (equal (len path) (* (len cycle) (len seen)))))
+ (consp (find-cycle cycle seen witness path))))
+)
+
+;; However, this leads us to two more proof requirements. Why should the
+;; witness be a member of seen, and why should the length of the big path be
+;; the product of the length of seen and cycle. We address these two issues
+;; below.
+
+(local
+(defthm snoc-produces-memberp
+ (memberp e (snoc x e)))
+)
+
+(local
+(defthm snoc-len-reduction
+ (equal (len (snoc x e))
+ (1+ (len x))))
+)
+
+;; We show that the value returned as the seen list has 1 less than what we
+;; need, and this will just be figured out by deducting 1 again from the seen
+;; list since we remove the last guy.
+
+(local
+(defthm len-of-path-is-product-of-two
+ (implies (equal (len path) (* (len cycle) (1- (len seen))))
+ (equal (len (mv-nth
+ 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)))
+ (* (len cycle)
+ (1- (len (mv-nth
+ 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars
+ path))))))))
+
+)
+
+(local
+(defthm len-of-path-is-product-of-two-2
+ (implies (equal (len path) (* (len cycle) (1- (len seen))))
+ (equal (len (mv-nth
+ 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)))
+ (* (len cycle)
+ (1- (len (mv-nth
+ 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars
+ path))))))))
+
+)
+
+
+(local
+(defthm del-last-len-reduction
+ (implies (consp x)
+ (equal (len (del-last x))
+ (1- (len x)))))
+)
+
+;; And finally that the seen list is consp
+
+(local
+(defthm seen-list-is-consp
+ (implies (memberp q seen)
+ (consp (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n cycle m seen
+ q states n
+ vars path))))
+
+)
+
+(local
+(defthm seen-list-is-consp-2
+ (implies (memberp q seen)
+ (consp (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m seen
+ q states m
+ cycle n
+ vars path))))
+
+)
+
+;; Now why should the witness be a member of the seen? The reason is kind of a
+;; pigeon-hole argument. The high-level argument is that witness is producing a
+;; a member of states all the time, and a new guy every time it produces a
+;; non-member of seen so it will exhaust out eventually.
+
+
+;; First a few reductions using snoc and uniquep. I am lucky that uniquep is
+;; already in records which helps a lot.
+
+(local
+(defthm snoc-member-reduction
+ (equal (memberp a (snoc x e))
+ (or (memberp a x)
+ (equal a e))))
+)
+
+(local
+(defthm uniquep-snoc-reduction
+ (implies (and (uniquep seen)
+ (not (memberp e seen)))
+ (uniquep (snoc seen e))))
+)
+
+(local
+(defthm memberp-del-last-reduction
+ (equal (memberp a (del-last (snoc x e)))
+ (memberp a x)))
+)
+
+(local
+(defthm uniquep-dellast-reduction
+ (implies (uniquep x)
+ (uniquep (del-last (snoc x e)))))
+)
+
+(local
+(defthm not-memberp-del-reduction
+ (implies (not (memberp e x))
+ (not (memberp e (del-last x)))))
+)
+
+(local
+(defthm uniquep-del-last-true
+ (implies (uniquep x)
+ (uniquep (del-last x))))
+)
+
+;; So now, we can show that the seen list is uniquep.
+
+(local
+(defthm del-last-seen-is-unique-p
+ (implies (uniquep seen)
+ (uniquep (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm del-last-seen-is-unique-p-2
+ (implies (uniquep seen)
+ (uniquep (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm len-<-states-implies-<witness-memberp
+ (implies (case-split (<= (len (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)))
+ (len states)))
+ (memberp (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))
+ (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))))))
+)
+
+(local
+(defthm len-<-states-implies-<witness-memberp-2
+ (implies (case-split (<= (len (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)))
+ (len states)))
+ (memberp (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))
+ (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))))))
+)
+
+(local
+(in-theory (enable subset))
+)
+
+;; Again, we need to define del. This is because it will be used in the
+;; induction hint. I am rpetty sure this is not the shortest path to the proof,
+;; but this is how I would have reasoned without ACL2.
+
+(local
+(defun del (e x)
+ (if (endp x) nil
+ (if (equal e (car x)) (cdr x)
+ (cons (car x) (del e (cdr x))))))
+)
+
+(local
+(defthm uniquep-to-not-member
+ (implies (uniquep x)
+ (not (memberp e (del e x)))))
+)
+
+(local
+(defthm member-del-reduction
+ (implies (not (equal a e))
+ (equal (memberp a (del e y))
+ (memberp a y))))
+)
+
+(local
+(defthm del-subset-reduction
+ (implies (and (uniquep x)
+ (subset x y))
+ (subset (del e x) (del e y))))
+)
+
+(local
+(defthm len-del-reduction
+ (implies (memberp e x)
+ (equal (len (del e x))
+ (1- (len x)))))
+)
+
+(local
+(defun induction-hint (x y)
+ (if (endp x) y
+ (induction-hint (rest x) (del (first x) y))))
+)
+
+(local
+(defthm not-memberp-del-reduction-2
+ (implies (not (memberp e x))
+ (subset x (del e x))))
+)
+
+(local
+(defthm unique-p-del-subset-reduction
+ (implies (and (uniquep x)
+ (not (memberp e x))
+ (subset x y))
+ (subset x (del e y)))
+ :hints (("Goal"
+ :do-not-induct t
+ :use ((:instance subset-is-transitive
+ (y (del e x))
+ (z (del e y)))))))
+)
+
+(local
+(defthm uniquep-subset-reduction
+ (implies (and (uniquep x)
+ (subset x y))
+ (<= (len x) (len y)))
+ :hints (("Goal"
+ :induct (induction-hint x y))))
+)
+
+(local
+(defthm car-append-reduction
+ (equal (car (append x y))
+ (if (consp x) (car x) (car y))))
+)
+
+(local
+(defthm consp-to-car-find-matching-path
+ (implies (consp path)
+ (equal (car (find-matching-path-for-path-m->n path m q n vars))
+ q)))
+)
+
+(local
+(defthm consp-to-car-find-matching-path-2
+ (implies (consp path)
+ (equal (car (find-matching-path-for-path-n->m q m path n vars))
+ q)))
+)
+
+(local
+(defthm last-val-append-reduction
+ (equal (last-val (append x y))
+ (if (consp y) (last-val y) (last-val x))))
+)
+
+(local
+(defthm subset-snoc-reduction
+ (implies (and (subset x y)
+ (memberp e y))
+ (subset (snoc x e) y)))
+)
+
+(local
+(defthm last-val-bisimilar-reduction
+ (implies (and (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (compatible-path-p cycle m))
+ (bisimilar (last-val cycle) m (last-val
+ (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ n vars)))
+)
+
+(local
+(defthm last-val-bisimilar-reduction-2
+ (implies (and (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (compatible-path-p cycle n))
+ (bisimilar (last-val (find-matching-path-for-path-n->m q m cycle n
+ vars))
+ m
+ (last-val cycle)
+ n vars)))
+)
+
+(local
+(defthm find-matching-path-produces-compatible-path
+ (implies (and (compatible-path-p cycle m)
+ (consp cycle)
+ (memberp q (states n))
+ (bisimilar (first cycle) m q n vars))
+ (compatible-path-p (find-matching-path-for-path-m->n
+ cycle m q n vars)
+ n)))
+)
+
+(local
+(defthm find-matching-path-produces-compatible-path-2
+ (implies (and (compatible-path-p cycle n)
+ (consp cycle)
+ (memberp q (states m))
+ (bisimilar q m (first cycle) n vars))
+ (compatible-path-p (find-matching-path-for-path-n->m
+ q m cycle n vars)
+ m)))
+)
+
+;; And finally, I am saying that seen list is a subset of states. (Basically a
+;; slightly stronger thing, but that is ok.)
+
+
+(local
+(defthm seen-list-subset-of-states
+ (implies (and (subset seen (states n))
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (compatible-path-p cycle m))
+ (subset (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))
+ (states n)))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm seen-list-subset-of-states-2
+ (implies (and (subset seen (states m))
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) n)
+ (compatible-path-p cycle n))
+ (subset (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))
+ (states m)))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+;; And also that witness is a member of states.
+
+(local
+(defthm witness-member-of-states
+ (implies (and (memberp q (states n))
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (compatible-path-p cycle m))
+ (memberp (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path))
+ (states n)))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q states n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm witness-member-of-states-2
+ (implies (and (memberp q (states m))
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) n)
+ (compatible-path-p cycle n))
+ (memberp (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path))
+ (states m)))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q states m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm subset-remains-for-del
+ (implies (subset x y)
+ (subset (del-last x) y)))
+)
+
+(local
+(defthm del-creates-subset
+ (subset (del-last x) x))
+)
+
+(local
+(defthm memberp-to-subset
+ (implies (memberp q states)
+ (subset (list q) states))
+ :rule-classes nil)
+)
+
+(local
+(defthm uniquep-and-=-and-implies-member
+ (implies (and (uniquep x)
+ (equal (len x) (len y))
+ (subset x y)
+ (memberp e y))
+ (memberp e x))
+ :hints (("Goal"
+ :induct (induction-hint x y))))
+)
+
+;; Then finally, I am done. I am saying here that the matching cycle is a
+;; consp. Matt might just not like the use hints I force, but there seems to be
+;; no simpler route. I would be interested to know if someone can simplify this
+;; proof.
+
+(local
+(defthm find-matching-cycle-for-cycle-is-consp
+ (implies (and (memberp q (states n))
+ (consp cycle)
+ (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (next-statep (last-val cycle) (first cycle) m))
+ (consp (find-matching-cycle-for-cycle-m->n cycle m q n vars)))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :expand (find-matching-cycle-for-cycle-m->n cycle m q n vars)
+ :do-not-induct t
+ :in-theory (disable witness-member-of-seen-implies-consp)
+ :use ((:instance witness-member-of-seen-implies-consp
+ (witness (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n)
+ n vars nil)))
+ (seen (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (path (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance uniquep-subset-reduction
+ (x (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil))))
+ (y (states n)))
+ (:instance uniquep-and-=-and-implies-member
+ (x (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n)
+ n vars nil))))
+ (y (states n))
+ (e (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n)
+ n vars nil))))))))
+)
+
+
+(local
+(defthm find-matching-cycle-for-cycle-is-consp-2
+ (implies (and (memberp q (states m))
+ (consp cycle)
+ (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (next-statep (last-val cycle) (first cycle) n))
+ (consp (find-matching-cycle-for-cycle-n->m q m cycle n vars)))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :expand (find-matching-cycle-for-cycle-n->m q m cycle n vars)
+ :do-not-induct t
+ :in-theory (disable witness-member-of-seen-implies-consp)
+ :use ((:instance witness-member-of-seen-implies-consp
+ (witness (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle
+ n vars nil)))
+ (seen (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (path (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance uniquep-subset-reduction
+ (x (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (y (states m)))
+ (:instance uniquep-and-=-and-implies-member
+ (x (del-last (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle
+ n vars nil))))
+ (y (states m))
+ (e (mv-nth 1 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n vars nil))))))))
+)
+
+;; The next theorem in our agenda is to prove that the prefix of the matching
+;; path is compatible-path-p. Notice we have already proved that
+;; find-matching-path produces a compatible-path-p. So we need to prove that
+;; prefix-and-cycle produces the same, and then say that append of two "good"
+;; compatible paths is a compatible path.
+
+(local
+(defthm compatible-path-append-reduction
+ (implies (force (and (true-listp x)
+ (true-listp y)))
+ (equal (compatible-path-p (append x y) m)
+ (if (not (consp x)) (compatible-path-p y m)
+ (if (not (consp y)) (compatible-path-p x m)
+ (and (compatible-path-p x m)
+ (compatible-path-p y m)
+ (next-statep (last-val x) (first y) m)))))))
+)
+
+
+;; While we are at it, let us show that the first-n and last-n are
+;; compatible-paths
+
+(local
+(defthm consp-and-i>=-first-n-reduction
+ (implies (and (consp p)
+ (integerp i)
+ (< 0 i))
+ (equal (car (first-n i p))
+ (car p))))
+)
+
+(local
+(defthm compatible-path-first-n-reduction
+ (implies (and (compatible-path-p p m)
+ (integerp i)
+ (<= 0 i)
+ (<= i (len p)))
+ (compatible-path-p (first-n i p) m))
+ :hints (("Goal"
+ :induct (first-n i p)
+ :in-theory (enable zp)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)
+ ("Subgoal *1/2"
+ :cases ((zp (1- i))))))
+)
+
+(local
+(defthm compatible-path-last-n-reduction
+ (implies (and (compatible-path-p p m)
+ (integerp i)
+ (<= 0 i)
+ (<= i (len p)))
+ (compatible-path-p (last-n i p) m))
+ :hints (("Goal"
+ :induct (last-n i p)
+ :in-theory (enable zp)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)
+ ("Subgoal *1/2"
+ :cases ((zp (1- i))))))
+)
+
+;; The theorems above just say that if we could (somehow) prove that
+;; find-prefix-and-cycle produces a compatible path then I would immediately
+;; know that the prefix and cycle are both compatible.
+
+;; Now why should find-prefix-and-cycle produce a compatible path? For
+;; something to be a compatible path, what we need is that every state in the
+;; path is a member of states and the next state is a next-statep. So let us
+;; prove these properties separately.
+
+;; Informally here is what happens. I know that the last-val of
+;; find-matching-path is bisimilar to last-val of cycle. and is a member of
+;; states. Hence, the bisimilar witness it produces with the first of cycle is
+;; a next-statep (Notice that next-statep is true for last-val and car of
+;; cycle.) Hence the paths produced by recursive calls can be appended together
+;; to produce a compatible path if path (the initial segment of the accumulator
+;; is known to be a compatible path.
+
+
+(local
+(defthm last-val-of-find-matching-prefix-is-member-of-states
+ (implies (and (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (compatible-path-p cycle m)
+ (memberp q (states n)))
+ (memberp (last-val (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ (states n))))
+)
+
+(local
+(defthm find-prefix-and-cycle-produces-compatible-path
+ (implies (and (bisimilar (first cycle) m q n vars)
+ (compatible-path-p path n)
+ (compatible-path-p (append path
+ (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ n)
+ (consp cycle)
+ (memberp q (states n))
+ (next-statep (last-val cycle) (car cycle) m)
+ (compatible-path-p cycle m))
+ (compatible-path-p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path))
+ n))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm find-prefix-and-cycle-produces-compatible-path-2
+ (implies (and (bisimilar q m (first cycle) n vars)
+ (compatible-path-p path m)
+ (compatible-path-p (append path
+ (find-matching-path-for-path-n->m
+ q m cycle n vars))
+ m)
+ (consp cycle)
+ (memberp q (states m))
+ (next-statep (last-val cycle) (car cycle) n)
+ (compatible-path-p cycle n))
+ (compatible-path-p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path))
+ m))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+;; Now that we know that find-prefix-and-cycle-is-a-compatible-path-p, and also
+;; that first-n of a compatible path is a compatible path, and also append
+;; produces compatible paths, we should be able to prove that
+;; find-matching-prefix and find-matching-cycle produce compatible paths.
+
+;; Well, it does not seem to be as simple as it looks. The problem is in
+;; getting the induction working right.
+
+;; To do work with find-matching-prefix we define the index such that
+;; find-prefix produces that index.
+
+
+(local
+(defun find-prefix-index (cycle seen witness path)
+ (cond ((endp path) 0)
+ ((endp seen) (len path))
+ ((equal witness (first seen)) 0)
+ (t (+ (len cycle)
+ (find-prefix-index cycle (rest seen) witness (last-n (len cycle) path))))))
+)
+
+(local
+(defthm first-n+-reduction
+ (implies (and (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j))
+ (equal (first-n (+ i j) x)
+ (append (first-n i x) (first-n j (last-n i x))))))
+)
+
+(local
+(defthm last-n+-reduction
+ (implies (and (integerp i)
+ (integerp j)
+ (<= 0 i)
+ (<= 0 j))
+ (equal (last-n (+ i j) x)
+ (last-n j (last-n i x)))))
+)
+
+(local
+(defthm find-prefix-with-index
+ (implies (and (true-listp path)
+ (equal (len path) (* (len cycle) (len seen))))
+ (equal (find-prefix cycle seen witness path)
+ (first-n (find-prefix-index cycle seen witness path) path))))
+)
+
+(local
+(defthm find-cycle-with-index
+ (implies (and (equal (len path) (* (len cycle) (len seen)))
+ (true-listp path))
+ (equal (find-cycle cycle seen witness path)
+ (last-n (find-prefix-index cycle seen witness path) path))))
+)
+
+(local
+(defthm index-is-an-integer->=0
+ (and (integerp (find-prefix-index cycle seen witness path))
+ (<= 0 (find-prefix-index cycle seen witness path)))
+ :rule-classes :type-prescription)
+)
+
+(local
+(defthm prefix-and-cycle-produces-true-listp
+ (implies (true-listp path)
+ (true-listp (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m q seen states n vars path)))))
+)
+
+(local
+(defthm prefix-and-cycle-produces-true-listp-2
+ (implies (true-listp path)
+ (true-listp (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ q seen states m cycle n vars path)))))
+)
+
+(local
+(in-theory (enable find-matching-cycle-for-cycle-m->n
+ find-matching-prefix-for-cycle-m->n))
+)
+
+(local
+(defthm last-consp-implies-first-<=len
+ (implies (and (consp (last-n i x))
+ (integerp i))
+ (<= i (len x)))
+ :rule-classes :linear)
+)
+
+(local
+(defthm find-matching-prefix-is-a-compatible-path
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (memberp q (states n))
+ (next-statep (last-val cycle) (car cycle) m))
+ (compatible-path-p (find-matching-prefix-for-cycle-m->n cycle m q n
+ vars)
+ n))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable compatible-path-first-n-reduction
+ find-matching-cycle-for-cycle-is-consp)
+ :use ((:instance compatible-path-first-n-reduction
+ (i (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (m n)
+ (p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp)))))
+)
+
+(local
+(defthm find-matching-cycle-is-a-compatible-path
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (memberp q (states n))
+ (next-statep (last-val cycle) (car cycle) m))
+ (compatible-path-p (find-matching-cycle-for-cycle-m->n cycle m q n
+ vars)
+ n))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable compatible-path-first-n-reduction
+ find-matching-cycle-for-cycle-is-consp)
+ :use ((:instance compatible-path-last-n-reduction
+ (i (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (m n)
+ (p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp)))))
+)
+
+(local
+(in-theory (enable find-matching-prefix-for-cycle-n->m
+ find-matching-cycle-for-cycle-n->m))
+)
+
+(local
+(defthm find-matching-prefix-is-a-compatible-path-2
+ (implies (and (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (memberp q (states m))
+ (next-statep (last-val cycle) (car cycle) n))
+ (compatible-path-p (find-matching-prefix-for-cycle-n->m q m cycle n
+ vars)
+ m))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable compatible-path-first-n-reduction
+ find-matching-cycle-for-cycle-is-consp-2)
+ :use ((:instance compatible-path-first-n-reduction
+ (i (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q)
+ q
+ (states
+ m) m
+ cycle n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states
+ m)
+ m
+ cycle n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q
+ (states m) m
+ cycle n
+ vars nil))))
+ (p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp-2)))))
+)
+
+
+(local
+(defthm find-matching-cycle-is-a-compatible-path-2
+ (implies (and (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (memberp q (states m))
+ (next-statep (last-val cycle) (car cycle) n))
+ (compatible-path-p (find-matching-cycle-for-cycle-n->m q m cycle n
+ vars)
+ m))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable compatible-path-last-n-reduction
+ find-matching-cycle-for-cycle-is-consp-2)
+ :use ((:instance compatible-path-last-n-reduction
+ (i (find-prefix-index
+ cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q)
+ q
+ (states
+ m) m
+ cycle n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states
+ m)
+ m
+ cycle n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q
+ (states m) m
+ cycle n
+ vars nil))))
+ (p (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp-2)))))
+)
+
+(local
+(defthm consp-last-next-state-p-reduction
+ (implies (and (compatible-path-p (append p q) m)
+ (true-listp p)
+ (true-listp q)
+ (consp p)
+ (consp q))
+ (next-statep (last-val p) (first q) m))
+ :rule-classes nil)
+)
+
+(local
+(defthm append-of-prefix-and-cycle-is-weird-path
+ (implies (and (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (equal (append (find-matching-prefix-for-cycle-m->n cycle m q n
+ vars)
+ (find-matching-cycle-for-cycle-m->n cycle m q n
+ vars))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n cycle m
+ (list q)
+ q
+ (states n) n
+ vars nil))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-matching-cycle-for-cycle-is-consp)
+ :use ((:instance first-last-append-reduction
+ (n (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (x (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp)))))
+)
+
+(local
+(defthm append-of-prefix-and-cycle-is-weird-path-2
+ (implies (and (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states m)))
+ (equal (append (find-matching-prefix-for-cycle-n->m q m cycle n
+ vars)
+ (find-matching-cycle-for-cycle-n->m q m cycle n
+ vars))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m (list q)
+ q
+ (states m) m
+ cycle n
+ vars nil))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-matching-cycle-for-cycle-is-consp-2)
+ :use ((:instance first-last-append-reduction
+ (n (find-prefix-index cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q
+ (states m)
+ m
+ cycle n
+ vars
+ nil)))
+
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states
+ m)
+ m
+ cycle n
+ vars nil))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q
+ (states m) m
+ cycle n
+ vars nil))))
+ (x (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance find-matching-cycle-for-cycle-is-consp-2)))))
+)
+
+(local
+(in-theory (disable append-of-prefix-and-cycle-is-weird-path
+ append-of-prefix-and-cycle-is-weird-path-2))
+)
+
+(local
+(defthm matching-cycle-is-true-listp
+ (true-listp (find-matching-cycle-for-cycle-m->n cycle m q n vars)))
+)
+
+(local
+(defthm matching-cycle-is-true-listp-2
+ (true-listp (find-matching-cycle-for-cycle-n->m q m cycle n vars)))
+)
+
+(local
+(defthm matching-prefix-is-true-listp
+ (true-listp (find-matching-prefix-for-cycle-m->n cycle m q n vars)))
+)
+
+(local
+(defthm matching-prefix-is-true-listp-2
+ (true-listp (find-matching-prefix-for-cycle-n->m q m cycle n vars)))
+)
+
+(local
+(defthm next-state-of-prefix-is-first-cycle
+ (implies (and (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (implies (consp (find-matching-prefix-for-cycle-m->n cycle m q n
+ vars))
+ (next-statep (last-val (find-matching-prefix-for-cycle-m->n
+ cycle m q n vars))
+ (first (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars))
+ n)))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-prefix-with-index
+ find-prefix-and-cycle-produces-compatible-path
+ find-matching-prefix-for-cycle-m->n
+ find-matching-cycle-for-cycle-m->n
+ find-cycle-with-index
+ find-matching-cycle-for-cycle-is-consp
+ find-matching-prefix-and-cycle-for-cycle-m->n)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path)
+ (:instance find-matching-cycle-for-cycle-is-consp)
+ (:instance find-prefix-and-cycle-produces-compatible-path
+ (seen (list q))
+ (path nil))
+ (:instance consp-last-next-state-p-reduction
+ (m n)
+ (p (find-matching-prefix-for-cycle-m->n
+ cycle m q n vars))
+ (q (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars)))))))
+)
+
+(local
+(defthm next-state-of-prefix-is-first-cycle-2
+ (implies (and (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states m)))
+ (implies (consp (find-matching-prefix-for-cycle-n->m q m cycle n
+ vars))
+ (next-statep (last-val (find-matching-prefix-for-cycle-n->m
+ q m cycle n vars))
+ (first (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars))
+ m)))
+ :otf-flg t
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-prefix-with-index
+ find-prefix-and-cycle-produces-compatible-path-2
+ find-matching-prefix-for-cycle-n->m
+ find-matching-cycle-for-cycle-n->m
+ find-cycle-with-index
+ find-matching-cycle-for-cycle-is-consp-2
+ find-matching-prefix-and-cycle-for-cycle-n->m)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path-2)
+ (:instance find-matching-cycle-for-cycle-is-consp-2)
+ (:instance find-prefix-and-cycle-produces-compatible-path-2
+ (seen (list q))
+ (path nil))
+ (:instance consp-last-next-state-p-reduction
+;; (m n)
+ (p (find-matching-prefix-for-cycle-n->m
+ q m cycle n vars))
+ (q (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars)))))))
+)
+
+;; So we have proved that matching-path is consp and that find-matching-prefix
+;; is compatible. Now we need to prove that last-val of matching-path and first
+;; of find-matching-prefix are next-states. Why is that? This is because
+;; last-val of find-matching-prefix is bisimilar to last-val of prefix, and we
+;; know that car of find-matching-prefix is the bisimilar witness.
+
+
+(local
+(defthm car-of-prefix-and-cycle
+ (implies (and (bisimilar (first cycle) m q n vars)
+ (force (<= (len seen) (len (states n))))
+ (compatible-path-p path n)
+ (compatible-path-p (append path
+ (find-matching-path-for-path-m->n
+ cycle m q n vars))
+ n)
+ (consp cycle)
+ (memberp q (states n))
+ (next-statep (last-val cycle) (car cycle) m)
+ (compatible-path-p cycle m))
+ (equal (car (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path)))
+ (if (consp path) (car path) q)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n cycle m seen q (states
+ n) n
+ vars
+ path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm car-of-prefix-and-cycle-2
+ (implies (and (bisimilar q m (first cycle) n vars)
+ (force (<= (len seen) (len (states m))))
+ (compatible-path-p path m)
+ (compatible-path-p (append path
+ (find-matching-path-for-path-n->m
+ q m cycle n vars))
+ m)
+ (consp cycle)
+ (memberp q (states m))
+ (next-statep (last-val cycle) (car cycle) n)
+ (compatible-path-p cycle n))
+ (equal (car (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path)))
+ (if (consp path) (car path) q)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m seen q (states
+ m)
+ m
+ cycle n
+ vars
+ path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(in-theory (disable find-matching-prefix-for-cycle-m->n
+ find-matching-cycle-for-cycle-m->n
+ find-matching-prefix-for-cycle-n->m
+ find-matching-cycle-for-cycle-n->m))
+)
+
+(local
+(defthm matching-prefix-consp
+ (implies (and (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars)
+ (true-listp cycle)
+ (consp cycle)
+ (memberp q (states n))
+ (consp (find-matching-prefix-for-cycle-m->n cycle m q n vars)))
+ (equal (car (find-matching-prefix-for-cycle-m->n cycle m q n vars))
+ (car (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil)))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable car-of-prefix-and-cycle
+ car-append-reduction
+ find-prefix-with-index find-cycle-with-index)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path)
+ (:instance car-append-reduction
+ (x (find-matching-prefix-for-cycle-m->n
+ cycle m q n vars))
+ (y (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars)))))))
+
+)
+
+(local
+(defthm matching-prefix-consp-2
+ (implies (and (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars)
+ (true-listp cycle)
+ (consp cycle)
+ (memberp q (states m))
+ (consp (find-matching-prefix-for-cycle-n->m q m cycle n vars)))
+ (equal (car (find-matching-prefix-for-cycle-n->m q m cycle n vars))
+ (car (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars nil)))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable car-of-prefix-and-cycle-2
+ car-append-reduction
+ find-prefix-with-index find-cycle-with-index)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path-2)
+ (:instance car-append-reduction
+ (x (find-matching-prefix-for-cycle-n->m
+ q m cycle n vars))
+ (y (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars)))))))
+
+)
+
+(local
+(defthm matching-prefix-not-consp
+ (implies (and (compatible-path-p cycle m)
+ (next-statep (last-val cycle) (first cycle) m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states n))
+ (not (consp (find-matching-prefix-for-cycle-m->n cycle m q n
+ vars))))
+ (equal (find-matching-cycle-for-cycle-m->n cycle m q n vars)
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :use append-of-prefix-and-cycle-is-weird-path)))
+)
+
+(local
+(defthm matching-prefix-not-consp-2
+ (implies (and (compatible-path-p cycle n)
+ (next-statep (last-val cycle) (first cycle) n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (true-listp cycle)
+ (memberp q (states m))
+ (not (consp (find-matching-prefix-for-cycle-n->m q m cycle n
+ vars))))
+ (equal (find-matching-cycle-for-cycle-n->m q m cycle n vars)
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars nil))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :use append-of-prefix-and-cycle-is-weird-path-2)))
+)
+
+;; The next and final property should be that the next state of the last of the
+;; cycle is the first of the cycle. Once I do that, I would go home-free with
+;; the final theorems.
+
+
+(local
+(defthm witness-is-next-state-of-last-val
+ (implies (and (consp cycle)
+ (true-listp cycle)
+ (subset seen (states n))
+ (uniquep seen)
+ (compatible-path-p cycle m)
+ (memberp q (states n))
+ (bisimilar (first cycle) m q n vars)
+ (next-statep (last-val cycle) (first cycle) m))
+ (next-statep (last-val
+ (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path)))
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path))
+ n)))
+)
+
+(local
+(defthm witness-is-next-state-of-last-val-2
+ (implies (and (consp cycle)
+ (true-listp cycle)
+ (subset seen (states m))
+ (uniquep seen)
+ (compatible-path-p cycle n)
+ (memberp q (states m))
+ (bisimilar q m (first cycle) n vars)
+ (next-statep (last-val cycle) (first cycle) n))
+ (next-statep (last-val
+ (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path)))
+ (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path))
+ m)))
+)
+
+;; OK, so we have proved that the witness is the next state of the
+;; last-val. Now of course, we have to know that the witness is the first thing
+;; that is picked up by find-cycle.
+
+
+(local
+(defun seen-compatible-with-path (cycle seen path)
+ (if (endp seen) (endp path)
+ (and (equal (car path) (car seen))
+ (seen-compatible-with-path cycle (rest seen) (last-n (len cycle) path)))))
+)
+
+(local
+(defthm consp-len-consp
+ (implies (and (consp cycle)
+ (<= (len cycle) (len q)))
+ (consp q))
+ :rule-classes nil)
+)
+
+(local
+(defthm consp-last-n-append-reduction
+ (implies (and (consp q)
+ (consp p))
+ (consp (last-n (len q) (append p q)))))
+)
+
+(local
+(defthm car-to-car-for-append
+ (implies (and (seen-compatible-with-path cycle seen (append p q))
+ (consp seen)
+ (force (consp p)))
+ (equal (car p) (car seen))))
+)
+
+(local
+(defthm snoc-car
+ (equal (car (snoc x e))
+ (if (consp x) (car x) e)))
+)
+
+(local
+(defthm last-n-not-consp
+ (not (consp (last-n (len p) p))))
+)
+
+(local
+(defthm last-append-reduction
+ (implies (and (integerp i)
+ (<= 0 i)
+ (<= i (len p)))
+ (equal (last-n i (append p q))
+ (append (last-n i p) q))))
+)
+
+(local
+(defthm len-<-1=>not-consp
+ (implies (< (len x) 1)
+ (not (consp x))))
+)
+
+(local
+(defthm snoc-append-compatible-reduction
+ (implies (and (seen-compatible-with-path cycle seen path)
+ (equal e (car q))
+ (consp q)
+ (force (equal (len path) (* (len cycle) (len seen))))
+ (force (<= (len cycle) (len path)))
+ (equal (len cycle) (len q)))
+ (seen-compatible-with-path cycle (snoc seen e) (append path q)))
+ :otf-flg t
+ :hints (("Goal"
+ :induct (seen-compatible-with-path cycle seen path)
+ :in-theory (disable first-last-append-reduction-2)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm find-prefix-and-cycle-has-seen-compatible
+ (implies (and (consp cycle)
+ (memberp q seen)
+ (true-listp seen)
+ (equal (len path) (* (len cycle) (1- (len seen))))
+ (seen-compatible-with-path cycle seen (append path
+ (find-matching-path-for-path-m->n
+ cycle m q n vars)))
+ (bisimilar (first cycle) m q n vars)
+ (<= (len seen) (len (states n)))
+ (next-statep (last-val cycle) (first cycle) m)
+ (compatible-path-p cycle m))
+ (seen-compatible-with-path cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars
+ path)))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars
+ path))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m seen q (states n) n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+(local
+(defthm find-prefix-and-cycle-has-seen-compatible-2
+ (implies (and (consp cycle)
+ (memberp q seen)
+ (true-listp seen)
+ (equal (len path) (* (len cycle) (1- (len seen))))
+ (seen-compatible-with-path cycle seen (append path
+ (find-matching-path-for-path-n->m
+ q m cycle n vars)))
+ (bisimilar q m (first cycle) n vars)
+ (<= (len seen) (len (states m)))
+ (next-statep (last-val cycle) (first cycle) n)
+ (compatible-path-p cycle n))
+ (seen-compatible-with-path cycle
+ (del-last (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m
+ cycle n vars
+ path)))
+ (mv-nth 2 (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m
+ cycle n vars
+ path))))
+ :hints (("Goal"
+ :induct (find-matching-prefix-and-cycle-for-cycle-n->m
+ seen q (states m) m cycle n vars path)
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t)))
+)
+
+
+(local
+(defthm car-is-witness
+ (implies (and (consp (find-cycle cycle seen witness path))
+ (seen-compatible-with-path cycle seen path))
+ (equal (car (find-cycle cycle seen witness path))
+ witness)))
+)
+
+(local
+(defthm last-val-of-cycle-is-last-val-of-prefix-and-cycle
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (equal (last-val (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars))
+ (last-val (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars
+ nil)))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-matching-prefix-and-cycle-for-cycle-m->n)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path)
+ (:instance find-matching-cycle-for-cycle-is-consp)
+ (:instance last-val-append-reduction
+ (x (find-matching-prefix-for-cycle-m->n
+ cycle m q n vars))
+ (y (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars)))))))
+)
+
+(local
+(defthm last-val-of-cycle-is-last-val-of-prefix-and-cycle-2
+ (implies (and (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) n)
+ (true-listp cycle)
+ (memberp q (states m)))
+ (equal (last-val (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars))
+ (last-val (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m cycle n vars
+ nil)))))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :do-not-induct t
+ :in-theory (disable find-matching-prefix-and-cycle-for-cycle-n->m)
+ :use ((:instance append-of-prefix-and-cycle-is-weird-path-2)
+ (:instance find-matching-cycle-for-cycle-is-consp-2)
+ (:instance last-val-append-reduction
+ (x (find-matching-prefix-for-cycle-n->m
+ q m cycle n vars))
+ (y (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars)))))))
+)
+
+(local
+(in-theory (disable find-prefix-with-index find-cycle-with-index))
+)
+
+(local
+(defthm del-last-has-len-<=-states
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (<= (len (del-last
+ (mv-nth 0 (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars nil))))
+ (len (states n))))
+ :hints (("Goal"
+ :do-not-induct t
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable uniquep-subset-reduction
+ del-last-seen-is-unique-p)
+ :use ((:instance uniquep-subset-reduction
+ (x (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n vars
+ nil))))
+ (y (states n)))
+ (:instance del-last-seen-is-unique-p
+ (seen (list q))
+ (states (states n))
+ (path nil)))))
+ :rule-classes :linear)
+)
+
+(local
+(defthm next-state-of-last-of-find-cycle-is-first-of-find-cycle
+ (implies (and (compatible-path-p cycle m)
+ (bisimilar (first cycle) m q n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) m)
+ (true-listp cycle)
+ (memberp q (states n)))
+ (next-statep (last-val (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars))
+ (first (find-matching-cycle-for-cycle-m->n
+ cycle m q n vars))
+ n))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable find-matching-cycle-for-cycle-is-consp
+ uniquep-subset-reduction
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle
+ car-is-witness
+ witness-is-next-state-of-last-val)
+ :do-not-induct t
+ :expand (find-matching-cycle-for-cycle-m->n cycle m q n vars)
+ :use ((:instance find-matching-cycle-for-cycle-is-consp)
+ (:instance witness-is-next-state-of-last-val
+ (path nil)
+ (seen (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil)))))
+ (:instance car-is-witness
+ (seen (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (witness (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil)))
+ (path (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-m->n
+ cycle m (list q) q (states n) n
+ vars nil))))
+ (:instance
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle)))
+ ("Subgoal 2.2"
+ :in-theory (disable find-prefix-and-cycle-has-seen-compatible)
+ :use ((:instance find-prefix-and-cycle-has-seen-compatible
+ (seen (list q))
+ (path nil))))
+ ("Subgoal 1"
+ :in-theory (enable find-matching-cycle-for-cycle-m->n))))
+)
+
+(local
+(defthm next-state-of-last-of-find-cycle-is-first-of-find-cycle-2
+ (implies (and (compatible-path-p cycle n)
+ (bisimilar q m (first cycle) n vars)
+ (consp cycle)
+ (next-statep (last-val cycle) (first cycle) n)
+ (true-listp cycle)
+ (memberp q (states m)))
+ (next-statep (last-val (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars))
+ (first (find-matching-cycle-for-cycle-n->m
+ q m cycle n vars))
+ m))
+ :hints (("Goal"
+ :do-not '(eliminate-destructors generalize)
+ :in-theory (disable find-matching-cycle-for-cycle-is-consp-2
+ uniquep-subset-reduction
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle-2
+ car-is-witness
+ witness-is-next-state-of-last-val-2)
+ :do-not-induct t
+ :expand (find-matching-cycle-for-cycle-n->m q m cycle n vars)
+ :use ((:instance find-matching-cycle-for-cycle-is-consp-2)
+ (:instance witness-is-next-state-of-last-val-2
+ (path nil)
+ (seen (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil)))))
+ (:instance car-is-witness
+ (seen (del-last
+ (mv-nth 0
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (witness (mv-nth 1
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil)))
+ (path (mv-nth 2
+ (find-matching-prefix-and-cycle-for-cycle-n->m
+ (list q) q (states m) m
+ cycle n
+ vars nil))))
+ (:instance
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle-2)))
+ ("Subgoal 2.2"
+ :in-theory (disable find-prefix-and-cycle-has-seen-compatible-2)
+ :use ((:instance find-prefix-and-cycle-has-seen-compatible-2
+ (seen (list q))
+ (path nil))))
+ ("Subgoal 1"
+ :in-theory (enable find-matching-cycle-for-cycle-n->m))))
+)
+
+(local
+(in-theory (disable witness-is-next-state-of-last-val
+ witness-is-next-state-of-last-val-2
+ consp-last-n-append-reduction
+ car-to-car-for-append
+ snoc-car
+ last-n-not-consp
+ last-n-append-reduction
+ len-<-1=>not-consp
+ snoc-append-compatible-reduction
+ find-prefix-and-cycle-has-seen-compatible
+ find-prefix-and-cycle-has-seen-compatible-2
+ car-is-witness
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle
+ last-val-of-cycle-is-last-val-of-prefix-and-cycle-2))
+)
+
+(local
+(defthm matching-ppath-is-compatible
+ (implies (and (compatible-ppath-p p m)
+ (modelp m)
+ (modelp n)
+ (bisimilar-equiv m n vars))
+ (compatible-ppath-p (find-matching-periodic-path-m->n p m n vars)
+ n))
+ :hints (("Goal"
+ :in-theory (disable modelp-characterization)
+ :use ((:instance modelp-characterization)
+ (:instance modelp-characterization (m n))))))
+
+)
+
+(local
+(defthm matching-ppath-is-compatible-2
+ (implies (and (compatible-ppath-p p n)
+ (modelp n)
+ (modelp m)
+ (bisimilar-equiv m n vars))
+ (compatible-ppath-p (find-matching-periodic-path-n->m m p n vars)
+ m))
+ :hints (("Goal"
+ :in-theory (disable modelp-characterization)
+ :use ((:instance modelp-characterization)
+ (:instance modelp-characterization (m n))))))
+)
+
+(local
+(in-theory (disable compatible-ppath-p find-matching-periodic-path-m->n
+ modelp-characterization restricted-formulap
+ find-matching-periodic-path-n->m))
+)
+
+(local
+(defthm bisimilar-models-have-same-ltl-semantics-1
+ (implies (and (bisimilar-equiv m n vars)
+ (modelp m)
+ (modelp n)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (restricted-formulap f vars))
+ (implies (ltl-semantics f m)
+ (ltl-semantics f n)))
+ :hints (("Goal"
+ :cases ((compatible-ppath-p (ltl-semantics-witness f n) n)))
+ ("Subgoal 1"
+ :in-theory (disable ltl-semantics-necc ltl-semantics-necc-expanded
+ ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ matching-ppath-is-compatible-2
+ ppath-and-its-matching-ppath-have-same-labels-2)
+ :use ((:instance ppath-and-its-matching-ppath-have-same-labels-2
+ (ppath (ltl-semantics-witness f n)))
+ (:instance ltl-semantics-necc-expanded
+ (ppath (find-matching-periodic-path-n->m
+ m (ltl-semantics-witness f n) n vars)))
+ (:instance matching-ppath-is-compatible-2
+ (p (ltl-semantics-witness f n)))
+ (:instance
+ ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ (p (find-matching-periodic-path-n->m
+ m (ltl-semantics-witness f n) n vars))
+ (q (ltl-semantics-witness f n)))))))
+)
+
+(local
+(defthm bisimilar-models-have-same-ltl-semantics-2
+ (implies (and (bisimilar-equiv m n vars)
+ (modelp m)
+ (modelp n)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (restricted-formulap f vars))
+ (implies (ltl-semantics f n)
+ (ltl-semantics f m)))
+ :hints (("Goal"
+ :cases ((compatible-ppath-p (ltl-semantics-witness f m) m)))
+ ("Subgoal 1"
+ :in-theory (disable ltl-semantics-necc ltl-semantics-necc-expanded
+ ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ matching-ppath-is-compatible
+ ppath-and-its-matching-ppath-have-same-labels)
+ :use ((:instance ppath-and-its-matching-ppath-have-same-labels
+ (ppath (ltl-semantics-witness f m)))
+ (:instance ltl-semantics-necc-expanded
+ (m n)
+ (ppath (find-matching-periodic-path-m->n
+ (ltl-semantics-witness f m) m n vars)))
+ (:instance matching-ppath-is-compatible
+ (p (ltl-semantics-witness f m)))
+ (:instance
+ ltl-ppath-semantics-cannot-distinguish-between-equal-labels
+ (q (find-matching-periodic-path-m->n
+ (ltl-semantics-witness f m) m n vars))
+ (p (ltl-semantics-witness f m)))))))
+)
+
+(local
+(in-theory (disable ltl-semantics ltl-semantics-necc ltl-semantics-necc-expanded))
+)
+
+(DEFTHM bisimilar-models-have-same-ltl-semantics
+ (implies (and (bisimilar-equiv m n vars)
+ (restricted-formulap f vars)
+ (subset vars (variables m))
+ (subset vars (variables n))
+ (modelp m)
+ (modelp n))
+ (equal (ltl-semantics f m)
+ (ltl-semantics f n)))
+ :hints (("Goal"
+ :use ((:instance bisimilar-models-have-same-ltl-semantics-1)
+ (:instance bisimilar-models-have-same-ltl-semantics-2))))
+ :rule-classes nil)
+
+
+
+
+