; $Id: readme-parens.txt 2476 2011-05-17 13:00:44Z schwicht $
readme file for minlog/examples/parsing/parens.scm
18.05.2011
Kenji Miyamoto
miyamoto@mathematik.uni-muenchen.de

This is a README file of the example parens.scm of Minlog.  It
describes the theory in the first section, and the formal proof on
Minlog in the second section.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 1. Theory

In this case study, we extract a parser program on parentheses from a
formal proof.  Details of each proof are explained in the next section
with formalized proofs on Minlog.  First, we give a grammar of our
sentence of parentheses in two ways.  They are equivalent and we use
whichever more convenient in each proposition.

grammar S
 E ::= Nil | EE | LER

grammar U
 E ::= Nil | ELER

where L and R are the left and the right parenthesis respectively.
Our sentence is formalized as a list of parentheses.  The algebra of
two nullary constructor,say L and R, is appropriate to represent our
parentheses, and the algebra of list should suffice to form a
sentence.  We refer the algebra of parentheses by "par" and list of it
by "list par".  Assume p be an element of par, x be an element of list
par.  list par is either (Nil par), an empty list, or p::x, a cons.
x: abbreviates x::(Nil par).  + is an appending of two lists.

These grammars are represented by inductively defined predicate
constants.  The definition of them are:

predicate S:
 S(Nil par)
 allnc x,y(S x -> S y -> S(x++y))
 allnc x(S x -> S(L::x++R:))

predicate U:
 U(Nil par)
 allnc x,y(U x -> U y -> U(x++(L::y++R:)))

The equivalence of two grammars are stated in the following way:

allnc x (U x -> S x)
allnc x (S x -> U x)

The first one is proven by the elimination axiom of U and the
introduction axioms of S.  The second one is by the elimination axiom
of S, the introduction axioms of U, and in addition we apply the
following lemma regarding the append operation of two lists.

allnc x,y (U x -> U y -> U (x++y))

The proof of this lemma is by the elimination axiom of U, the
introduction axiom of U, and also the associativity of the list append
operation.  he associativity is proven in the library for the list.

We introduce a constant Test with computation rules in order to
provide a parser.  The soundness and the completeness of this parser
holds with respect to our grammar, thus we can extract from a proof of
the soundness and the completeness a program to determine the
grammatical correctness of the given sentence.

Test is of type nat=>list par=>boole, with the following computation rules:
Test 0(Nil par) = True
Test 0(R::x) = False
Test(Succ n)(Nil par) = False
Test n(L::x) = Test(Succ n)x
Test(Succ n)(R::x) = Test n x

It should be proven that Test works as a total function.  In another
word, it has to be guaranteed that the output of Test is True or
False, i.e. a total ideal of boole, if two inputs are total.  The
proof is done through a lemma stating if n x are total, Test n x is
total.  The totality of Test is a simple consequence of it.  We prove
the lemma by general induction.  We apply general induction to the
claim with a measure function

f(n,x) = n+2*Length(x)

The rest of the proof involves a couple of case distinctions.  See
details in the next section of this file.

Another lemma TestProp is also proven.  This lemma states that the
Test is preserved with respect to the addition of the first arguments
and appending of the second arguments.

all n,m,x,y(Test n x -> Test m y -> Test (n+m) (x++y))

We call it TestProp.  The proof is by induction and
Ex-Falso-Quodlibet.

The soundness is written down by using U.

allnc u (U u -> Test 0 u)

The proof is done by means of TestProp and the elimination axiom of U.

To prove the completeness of Test regarding the grammar, we define a
predicate State.  State works in an opposite way of Test.  Test n x
holds if x contains n superfluous R.  On the other way around, State n
x holds if x contains n superfluous L, and in addition x does not end
with R.  The definition of State comes from the stack of the
shift-reduce parser.

We take the following shift-reduce parser for our grammar:

Shift   (state,         s, L::y) -> (state*(s,L), Nil,            y)
Reduce  (state *(s1,L), s, R::y) -> (state,       s1++(L::s)++R:, y)
Finish  (init,          s, Nil)  -> s       

They are described with triples consisting a stack, a symbol, and an
input.

The stack has symbols with the recognized input.  Our predicate State
takes care of the stack of this parser machine.  Elements of stack has
a simplification which allows us to forget pushing L.  It is due to
the fact that the push happens only when the machine faced L.  In
fact, we don't have L in our actual stack.

The symbol is a representation of a non-terminal symbol in a list of
parentheses.  In our case, each symbol tells the expression of
x++(L::y)++R: which is a representation of the right hand side of the
generating grammar

E -> ELER

When the machine faced R, it triggers the reduction which requires
what E is in the right hand side of the above grammar.  Then it pops
the stack and takes a current symbol to write a parsed sentence as the
next symbol.

We prove a Parse lemma which is a formal statement of the fact that
unbalanced superfluous L parentheses are closed by the same number of
R parentheses.

all y allnc n,x (State n x -> allnc s(S s -> Test n y -> S (x++s++y)))

It claims that if x contains n superfluous L, s follows the grammar,
and y contains n superfluous R, x++s++y follows the grammar.  One can
get what it says by thinking how superfluous L in x are closed.

The completeness is a consequence of this Parse lemma.

all x(Test 0 x -> S x)

In addition, we prove CompleteSound claiming the decidability of an
arbitrary sentence with respect to our grammar.

all x ex p((p -> S x) & ((p -> F) -> S x -> F))

From the proof of CompleteSound we extract a program to be a parser.
Applying this program to L::R: results True@cApS cInitS(cParS cInitS).
It shows that the input is grammatically correct and also the parse
tree of the input in the right of the pairing.

Applying the program to R::L: results False@cInitS.  The left of the
paring shows that the input is grammatically wrong, and the null parse
tree in the right.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 2. Formal Proof on Minlog

(The line numbers L20 etc. refer to the file parens.scm).

L20 In this case study strings are expressed by a list of the left and
the right parentheses.  First we load Minlog and libraries for natural
numbers and lists.

L27 The parentheses are represented by an algebra "par" consisting two
constructors "L" and "R", to be the left and the right parentheses
respectively.  The following two lines of add-var-name are variable
declarations.

L39 The two grammars are given by inductively defined predicate
constants "U" and "S".  "++" in the definition means a function to
append two lists.  One can find its definition in the library file
"minlog/lib/list.scm".  In add-ids we give the names "algU" and "algS"
to be the types of the realizers of predicates "U" and "S"
respectively.

The definitions of these types of the realizers are yielded from the
given definitions for the predicates "U" and "S".  Minlog takes care
of it by add-alg inside of add-ids, and they can be referred by the
given names later.  We can see the defined algebras by
(display-constructors "algU" "algS") after defining these predicates.

(display-constructors "algU" "algS")
; algU
; 	cInitU:	algU
; 	cApU:	algU=>algU=>algU
; algS
; 	cInitS:	algS
; 	cApS:	algS=>algS=>algS
; 	cParS:	algS=>algS

algU is the algebra of binary trees and algS is the algebra of trees
with two kinds of branches; one is binary and the other is unary.  If
we have defined an isomorphic algebra to the type of the realizer,
this isomorphic one can be specified instead of a name of an algebra
to be defined by add-ids.  add-ids adopts the given algebra to be the
type of the realizer by checking whether the given algebra is
isomorphic to the expected algebra of the realizer.  It shows an error
message if the given algebra is unsuitable.

L49

(set-goal (pf "allnc x(U x -> S x)"))
; ?_1: allnc x(U x -> S x)

A proposition to tell the inclusion of the grammar U in S is shown as
follows.

(assume "x" "IdHyp")
; ?_2: S x from
;   {x}  IdHyp:U x
(elim "IdHyp")
; ok, ?_2 can be obtained from
; ?_4: allnc x,y(U x -> U y -> S x -> S y -> S(x++(L::y++R:))) from
;   {x}  IdHyp:U x

; ?_3: S(Nil par) from
;   {x}  IdHyp:U x

We assume "x" and "U x" by "assume", and show "S x" by the following
elimination axiom of "U x":

allnc x(U x -> P(Nil par) ->
              allnc x,y(U x -> U y -> P x -> P y -> P(xLyR)) ->
        P x)

which is applied by "elim".

L52

To suit the current goal "S x" the competitor predicate P is
instantiated by S.  U x is given as an argument "IdHyp" of elim.

(use "InitS")
; ok, ?_3 is proved.  The active goal now is
; ?_4: allnc x,y(U x -> U y -> S x -> S y -> S(x++(L::y++R:))) from
;   {x}  IdHyp:U x
S(Nil par) is trivial from "InitS".

L53

(assume "x1" "y" "U x1" "U y" "S x1" "S y")
; ok, we now have the new goal 
; ?_5: S(x1++(L::y++R:)) from
;   {x}  IdHyp:U x
;   {x1}  {y}  U x1:U x1
;   U y:U y
;   S x1:S x1
;   S y:S y
(use "ApS")
; ok, ?_5 can be obtained from
; ?_7: S(L::y++R:) from
;   {x}  IdHyp:U x
;   {x1}  {y}  U x1:U x1
;   U y:U y
;   S x1:S x1
;   S y:S y

; ?_6: S x1 from
;   {x}  IdHyp:U x
;   {x1}  {y}  U x1:U x1
;   U y:U y
;   S x1:S x1
;   S y:S y

L55 In order to show allnc x,y(U x -> U y -> S x -> S y -> S(xLyR)) we
assume x,y,U x,U y,S x and S y.  By "ApS" it suffices to show "S x"
and "S (LyR)".

(auto)
; ;   The active goal now is
; ?_7: S(L::y++R:) from
;   {x}  IdHyp:U x
;   {x1}  {y}  U x1:U x1
;   U y:U y
;   S x1:S x1
;   S y:S y

L56 We have "S x" in the assumptions.  auto takes care of this trivial
goal.

(use "ParS")
; ok, ?_7 can be obtained from
; ?_8: S y from
;   {x}  IdHyp:U x
;   {x1}  {y}  U x1:U x1
;   U y:U y
;   S x1:S x1
;   S y:S y
(auto)
; ; Proof finished.

"S y" yields "S (LyR)" by "ParS".  Both of these new goals are proven
by auto.

L59

(save "US")
; ok, US has been added as a new theorem.
; ok, program constant cUS: algU=>algS
; of t-degree 0 and arity 0 added

The save command assigns a name to the current proof.

L61 "proof-to-extracted-term" extracts program from a proof.  We
obtain the proof object of the above proof by "theorem-name-to-proof"
and obtain the extracted term as a Scheme object.  The term can be
normalized by "nt" which stands for normalize term.

L64 "pp" prints the normalized term in a readable format.


L71 We show that the appending of two sentences in the grammar U follows
the grammar U.

(set-goal (pf "allnc x,y(U x -> U y -> U(x++y))"))
; ?_1: allnc x,y(U x -> U y -> U(x++y))
(assume "x" "y" "U x" "IdHyp")
; ok, we now have the new goal 
; ?_2: U(x++y) from
;   {x}  {y}  U x:U x
;   IdHyp:U y

L73 First we assume x, y, U x and IdHyp, and call elim with IdHyp to apply
the elimination axiom of U.

(elim "IdHyp")
; ok, ?_2 can be obtained from
; ?_4: allnc x2802,y(
;       U x2802 -> 
;       U y -> U(x++x2802) -> U(x++y) -> U(x++(x2802++(L::y++R:)))) from
;   {x}  {y}  U x:U x
;   IdHyp:U y

; ?_3: U(x++(Nil par)) from
;   {x}  {y}  U x:U x
;   IdHyp:U y

L74 We prove U(x++(Nil par)) first.  auto applies the equality between
x++Nil and x which comes from the theorem proven in list.scm.  It also
finds U x from the context to prove.

(auto)
; ;   The active goal now is
; ?_4: allnc x2810,y(
;       U x2810 -> 
;       U y -> U(x++x2810) -> U(x++y) -> U(x++(x2810++(L::y++R:)))) from
;   {x}  {y}  U x:U x
;   IdHyp:U y
(assume "x1" "y1" "U x1" "U y1" "U(x++x1)" "U(x++y1)")
(simp "ListAppdAssoc")

We prove U(x++(x2810++(L::y++R:))) under assumptions.  The statement
of the theorem "ListAppdAssoc" is as follows: all xs1,xs2,xs3
xs1++(xs2++xs3)eqd xs1++xs2++xs3

L77 simp rewrites the argument of U in the goal from the left hand
side of the statement to the right hand one.

; ok, we now have the new goal 
; ?_5: U(x++(x1++(L::y1++R:))) from
;   {x}  {y}  U x:U x
;   IdHyp:U y
;   {x1}  {y1}  U x1:U x1
;   U y1:U y1
;   U(x++x1):U(x++x1)
;   U(x++y1):U(x++y1)
; ok, ?_5 can be obtained from
; ?_6: U(x++x1++(L::y1++R:)) from
;   {x}  {y}  U x:U x
;   IdHyp:U y
;   {x1}  {y1}  U x1:U x1
;   U y1:U y1
;   U(x++x1):U(x++x1)
;   U(x++y1):U(x++y1)
(use "ApU")
(auto)
(save "AppendU")

ApU reduces the goal into U(x++x1) and U y1, which are both in the
context.

L89 Now the inclusion of the grammar S in U is proven.

(set-goal (pf "allnc x(S x -> U x)"))
; ?_1: allnc x(S x -> U x)

(assume "x" "IdHyp")
; ok, we now have the new goal 
; ?_2: U x from
;   {x}  IdHyp:S x

The elimination axiom of S is

all x(S x -> P (Nil par) ->
             all x,y(S x -> S y -> P x -> P y -> P(x+y)) ->
	     all x(S x -> P x -> P(LxR)) ->
	     P x)

which we apply to U x.

L92

(elim "IdHyp")
; ok, ?_2 can be obtained from
; ?_5: allnc x(S x -> U x -> U(L::x++R:)) from
;   {x}  IdHyp:S x

; ?_4: allnc x,y(S x -> S y -> U x -> U y -> U(x++y)) from
;   {x}  IdHyp:S x

; ?_3: U(Nil par) from
;   {x}  IdHyp:S x
(use "InitU")
(assume "x1" "y" "S x1" "S y" "U x1" "U y")
(use "AppendU")
(auto)

We prove U(Nil par) by InitU.  allnc x,y(S x -> S y -> U x -> U y ->
U(x++y)) is done by assuming premises and applying AppendU and auto
afterwards.

L97

; ;   The active goal now is
; ?_5: allnc x(S x -> U x -> U(L::x++R:)) from
;   {x}  IdHyp:S x
(assume "x1" "S x1" "U x1")
; ok, we now have the new goal 
; ?_9: U(L::x1++R:) from
;   {x}  IdHyp:S x
;   {x1}  S x1:S x1
;   U x1:U x1
(assert (pf "U((Nil par)++(L::x1++R:))"))
; ok, ?_9 can be obtained from
; ?_10: U((Nil par)++(L::x1++R:)) -> U(L::x1++R:) from
;   {x}  IdHyp:S x
;   {x1}  S x1:S x1
;   U x1:U x1

; ?_11: U((Nil par)++(L::x1++R:)) from
;   {x}  IdHyp:S x
;   {x1}  S x1:S x1
;   U x1:U x1

We assume "x1", "S x1", and "U x1" and assert "U((Nil
par)++(L::x1++R:))" in order to prove U(L::x++R:).  This assertion
gives a proposision with the same form of one occur in ApU as follows:

allnc x,y(U x -> U y -> U(x++(L::y++R:)))

L99 Thus we use it.

; ok, we now have the new goal 
; ?_9: U(L::x1++R:) from
;   {x}  IdHyp:S x
;   {x1}  S x1:S x1
;   U x1:U x1
 (use "ApU")
; ok, ?_11 can be obtained from
; ?_13: U x1 from
;   {x}  IdHyp:S x
;   {x1}  S x1:S x1
;   U x1:U x1

; ?_12: U(Nil par) from
;   {x}  IdHyp:S x
;   {x1}  S x1:S x1
;   U x1:U x1
 (use "InitU")
 (auto)
(save "SU")

InitU and U x1 in the context finish the proof.  We name "SU" for the
above proof.

The extracted term is obtained as the previous cases.  Recall that we
applied a lemma AppendU in the proof of "SU".  Now there is an
occurrence of something came from the proof of "AppendU" in the
extracted term of "SU" as follows:

L105

(define eterm (proof-to-extracted-term (theorem-name-to-proof "SU")))
(pp (nt eterm))

The output of pp is:

; [b0](Rec algS=>algU)b0 cInitU([b1,b2]cAppendU)([b1]cApU cInitU)

Minlog gives the lemma AppendU a name cAppendU which is actually a
constant.  Since we have already proven this lemma in a constructive
way, the computational content from the lemma is available.  It
results in a computation rule for cAppendU and we can enable this rule
by animate it.

(animate "AppendU")
; ok, computation rule cAppendU -> [a0,a1](Rec algU=>algU)a1 a0([a2,a3,a4,a5](cEqDCompatRev algU)(cApU a4 a3)) added
(pp (nt eterm))

The output of pp is:

; [b0]
;  (Rec algS=>algU)b0 cInitU
;  ([b1,b2,a3,a4]
;    (Rec algU=>algU)a4 a3([a5,a6,a7,a8](cEqDCompatRev algU)(cApU a7 a6)))
;  ([b1]cApU cInitU)

In contrast to the previous output, we see that the above computation
rule of cAppendU is applied to the term.

So far we have shown that the predicates U and S express the same
grammar.  We add a constant "Test" to be a parser and show the
soundness and the completeness of "Test" with respect to the grammar.

L117 add-program-constant declares a new programmable constant name
with a specified type.  Our constant "Test" is of type "nat=>list
par=>boole".

L119 add-computation-rules defines a computation rule for a
programmable constant.  The given computation rule in our case study
is supposed to parse the parentheses expression and tells whether it
follows the grammar.

We prove three propositions "TestTotalAux", "TestTotal" and "TestProp"
in order to show the soundness and the completeness.  "TestTotal"
tells the totality of "Test", namely if the given arguments n of nat
and x of list par are total ideals, the term "Test n x" denotes a
total ideal of type "boole".  This proposition is shown through an
auxiliary lemma "TestTotalAux" as follows.

L129 We show "all n,x (Total (Test n x))" by general induction "gind"

all mu,v(Prog_v^mu (P v) -> P v)

where Prog_v^mu (P v) := all v((all w(mu w < mu v -> P w)) -> P v)

(set-goal (pf "all n,x Total(Test n x)"))
; ?_1: all n,x Total(Test n x)
(gind (pt "[n,x]n+2*Lh x"))
; ok, ?_1 can be obtained from
; ?_2: all n2881,x2882(
;       all n2883,x2884(
;        ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n2881 x2882 -> 
;        Total(Test n2883 x2884)) -> 
;       Total(Test n2881 x2882)) from
;   n2877  x2876

We give "[n,x]n+2*(Lh x)" to be a measure function of general
induction.  Note that "Lh" computes the length of the given list.

General induction is instantiated as

all n,x(all n,x(all m,y(mu m y < mu n x -> Total(Test m y)) -> Total(Test n x))
        -> Total(Test n x))

We have to show all n,x(all m,y(mu m y < mu n x -> Total(Test m y)) ->
Total(Test n x)) in order to prove the proposition.

L131

(assume "n" "x" "Prog")
; ok, we now have the new goal 
; ?_3: Total(Test n x) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))

We assume n,x, and all m,y(mu m y < mu n x -> Total(Test m y)) by
"assume".  It is shown by two case distinctions on x whether it is Nil
or Cons.

L132

(cases (pt "x"))
; ok, ?_3 can be obtained from
; ?_5: all par2891,x2892(x=(par2891::x2892) -> Total(Test n(par2891::x2892))) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))

; ?_4: x=(Nil par) -> Total(Test n(Nil par)) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))

In the case of Nil, we are done by case distinction on n.

L133

(assume "x=(Nil par)")
; ok, we now have the new goal 
; ?_6: Total(Test n(Nil par)) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)
(cases (pt "n"))
; ok, ?_6 can be obtained from
; ?_8: all n2895(n=Succ n2895 -> Total(Test(Succ n2895)(Nil par))) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)

; ?_7: n=0 -> Total(Test 0(Nil par)) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)

L135

(strip)
(ng)
(use (make-proof-in-aconst-form (finalg-to-e-to-total-aconst (py "boole"))))
(use "Truth-Axiom")
; ok, we now have the new goal 
; ?_9: Total(Test 0(Nil par)) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)
;   3:n=0
> ; ok, the normalized goal is
; ?_10: Total True from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      n2883+Lh x2884+Lh x2884<n+Lh x+Lh x -> Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)
;   3:n=0
> ; ok, ?_10 can be obtained from
; ?_11: E True from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      n2883+Lh x2884+Lh x2884<n+Lh x+Lh x -> Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)
;   3:n=0
> ; ok, ?_11 is proved.  The active goal now is
; ?_8: all n2899(n=Succ n2899 -> Total(Test(Succ n2899)(Nil par))) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)

The other case is one in the same way.

L139

(strip)
(ng)
(use (make-proof-in-aconst-form (finalg-to-e-to-total-aconst (py "boole"))))
(use "Truth-Axiom")
; ok, we now have the new goal 
; ?_12: Total(Test(Succ n2899)(Nil par)) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)
;   n2899  3:n=Succ n2899
> ; ok, the normalized goal is
; ?_13: Total False from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      n2883+Lh x2884+Lh x2884<n+Lh x+Lh x -> Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)
;   n2899  3:n=Succ n2899
> ; ok, ?_13 can be obtained from
; ?_14: E False from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      n2883+Lh x2884+Lh x2884<n+Lh x+Lh x -> Total(Test n2883 x2884))
;   x=(Nil par):x=(Nil par)
;   n2899  3:n=Succ n2899
> ; ok, ?_14 is proved.  The active goal now is
; ?_5: all par2891,x2892(x=(par2891::x2892) -> Total(Test n(par2891::x2892))) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))

In the case of Cons, we do the case distinction on the first element
of the parentheses list.

L144

(cases)
; ok, ?_5 can be obtained from
; ?_16: all x2892(x=(R::x2892) -> Total(Test n(R::x2892))) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   par2905

; ?_15: all x2892(x=(L::x2892) -> Total(Test n(L::x2892))) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   par2905

For the case of L at the first element of the list, we assume the
quantified variable and the premise.

L145

(assume "x1" "x=(L::x1)")
; ok, we now have the new goal 
; ?_17: Total(Test n(L::x1)) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   par2900  x1  x=(L::x1):x=(L::x1)

By normalizing the goal we obtain a goal which is suitable to apply
Prog from the context.

L146

(ng)
; ok, the normalized goal is
; ?_18: Total(Test(Succ n)x1) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      n2883+Lh x2884+Lh x2884<n+Lh x+Lh x -> Total(Test n2883 x2884))
;   par2900  x1  x=(L::x1):x=(L::x1)
(use "Prog")
; ok, ?_18 can be obtained from
; ?_19: Succ n+Lh x1+Lh x1<n+Lh x+Lh x from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      n2883+Lh x2884+Lh x2884<n+Lh x+Lh x -> Total(Test n2883 x2884))
;   par2900  x1  x=(L::x1):x=(L::x1)

Since x is L::x1 the inequality holds.  It comes from the assumpsions.

L148

(simp "x=(L::x1)")
; ok, ?_19 can be obtained from
; ?_20: Succ n+Lh x1+Lh x1<n+Lh(L::x1)+Lh(L::x1) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      n2883+Lh x2884+Lh x2884<n+Lh x+Lh x -> Total(Test n2883 x2884))
;   par2900  x1  x=(L::x1):x=(L::x1)
(ng)
; ok, the normalized goal is
; ?_21: T from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      n2883+Lh x2884+Lh x2884<n+Lh x+Lh x -> Total(Test n2883 x2884))
;   par2900  x1  x=(L::x1):x=(L::x1)
(use "Truth-Axiom")
; ok, ?_21 is proved.  The active goal now is
; ?_16: all x2892(x=(R::x2892) -> Total(Test n(R::x2892))) from
;   n2877  x2876  n  x  Prog:
;     all n2883,x2884(
;      ([n,x]n+2*Lh x)n2883 x2884<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2883 x2884))
;   par2900

For the other case we do the case distinction on n.

L151

(assume "x1" "x=(R::x1)")
(cases (pt "n"))
; ok, ?_22 can be obtained from
; ?_24: all n3090(n=Succ n3090 -> Total(Test(Succ n3090)(R::x1))) from
;   n3052  x3051  n  x  Prog:
;     all n3058,x3059(
;      ([n,x]n+2*Lh x)n3058 x3059<([n,x]n+2*Lh x)n x -> 
;      Total(Test n3058 x3059))
;   par3075  x1  x=(R::x1):x=(R::x1)

; ?_23: n=0 -> Total(Test 0(R::x1)) from
;   n3052  x3051  n  x  Prog:
;     all n3058,x3059(
;      ([n,x]n+2*Lh x)n3058 x3059<([n,x]n+2*Lh x)n x -> 
;      Total(Test n3058 x3059))
;   par3075  x1  x=(R::x1):x=(R::x1)

The case of Zero is done through the totality of False.

L153

(strip)
(ng)
; ok, the normalized goal is
; ?_26: Total False from
;   n3052  x3051  n  x  Prog:
;     all n3058,x3059(
;      n3058+Lh x3059+Lh x3059<n+Lh x+Lh x -> Total(Test n3058 x3059))
;   par3075  x1  x=(R::x1):x=(R::x1)
;   3:n=0
(use (make-proof-in-aconst-form (finalg-to-e-to-total-aconst (py "boole"))))
; ok, ?_26 can be obtained from
; ?_27: E False from
;   n3052  x3051  n  x  Prog:
;     all n3058,x3059(
;      n3058+Lh x3059+Lh x3059<n+Lh x+Lh x -> Total(Test n3058 x3059))
;   par3075  x1  x=(R::x1):x=(R::x1)
;   3:n=0
(use "Truth-Axiom")
; ok, ?_27 is proved.  The active goal now is
; ?_24: all n2964(n=Succ n2964 -> Total(Test(Succ n2964)(R::x1))) from
;   n2926  x2925  n  x  Prog:
;     all n2932,x2933(
;      ([n,x]n+2*Lh x)n2932 x2933<([n,x]n+2*Lh x)n x -> 
;      Total(Test n2932 x2933))
;   par2949  x1  x=(R::x1):x=(R::x1)

The case for the successor is also done by Prog.  Assuming
assumptions, we apply Prog to Total(Test(Succ n2964)(R::x1)).

L157

(assume "n1" "n=Succ n1")
(ng)
(use "Prog")
; ok, ?_29 can be obtained from
; ?_30: n1+Lh x1+Lh x1<n+Lh x+Lh x from
;   n3052  x3051  n  x  Prog:
;     all n3058,x3059(
;      n3058+Lh x3059+Lh x3059<n+Lh x+Lh x -> Total(Test n3058 x3059))
;   par3075  x1  x=(R::x1):x=(R::x1)
;   n1  n=Succ n1:n=Succ n1

This goal is straightforward from the condition on n and x.

L160

(simp "n=Succ n1")
(ng)
(simp "x=(R::x1)")
(ng)
(use "NatLtTrans" (pt "Succ(n1+Lh x1+Lh x1)"))
(auto)
(ng)
(use "NatLtTrans" (pt "Succ(n1+Lh x1+Lh x1)"))
; ?_38: n1+Lh x1+Lh x1<Succ(n1+Lh x1+Lh x1) from
;   n3052  x3051  n  x  Prog:
;     all n3058,x3059(
;      n3058+Lh x3059+Lh x3059<n+Lh x+Lh x -> Total(Test n3058 x3059))
;   par3075  x1  x=(R::x1):x=(R::x1)
;   n1  n=Succ n1:n=Succ n1
(auto)
; ; Proof finished.
(save "TestTotalAux")
; ok, TestTotalAux has been added as a new theorem.

We applied a theorem NatLeTrans from the library nat.scm.  TestTotal
is a consequence of TestTotalAux.  We use the axioms Total and
All-AllPartial in our proof: Let f be of type alpha=>beta, x be of
type alpha.  Total is a theorem defined on a predicate constant Total
by

all f^((Total f^ -> all x^(Total x^ -> Total (f^ x^)) &
        all x^(Total x^ -> Total (f^ x^)) -> Total f^) -> Total f^)

which we use to prove the totality of higher type terms.
All-AllPartial is all y(P y -> all x^(Total x^ -> P x^)) where P is a
predicate of arity (alpha) and y^ is a partial variable of type alpha.
First we apply Total by letting alpha be nat and beta be list
par=>boole,

L173

(set-goal (pf "Total Test"))
; ?_1: Total Test
(use "Total")
; ok, ?_1 can be obtained from
; ?_2: all n^3384(Total n^3384 -> Total(Test n^3384))

Next, we apply All-AllPartial with letting P be {x | Total(Test x)}.

L175

(use "All-AllPartial")
; ok, ?_2 can be obtained from
; ?_3: all n3457 Total(Test n3457)
(assume "n")
; ok, we now have the new goal 
; ?_4: Total(Test n) from
;   n

Now we see that the order of the argument of Total is one less than
the beginning.  We again apply Total and All-AllPartial to decrease
the order of the argument of Total to the base type.

L177

(use "Total" 'right)
; ok, ?_4 can be obtained from
; ?_5: all x^3481(Total x^3481 -> Total(Test n x^3481)) from
;   n
(use "All-AllPartial")
; ok, ?_5 can be obtained from
; ?_6: all x3499 Total(Test n x3499) from
;   n

Now the goal is immediate from TestTotalAux.

L179

(use "TestTotalAux")
; ok, ?_6 is proved.  Proof finished.

We save TestTotal.

L181

(save "TestTotal")
; ok, TestTotal has been added as a new theorem.
; ok, computation rule Test 0(Nil par) -> True added
; ok, computation rule Test 0(R::x) -> False added
; ok, computation rule Test(Succ n)(Nil par) -> False added
; ok, computation rule Test n(L::x) -> Test(Succ n)x added
; ok, computation rule Test(Succ n)(R::x) -> Test n x added

This save command updates Test because Minlog now knows that Test is a
total functional.  When we defined the computation rules of Test by
add-computation-rule, the totality degree of Test was 0, namely it was
supposed to be a partial functional.  However after proving TestTotal,
the totality degree of Test is 1, which means total.

(term-to-t-deg (pt "Test"))
; 1

TestProp tells that the gramatical correctness is preserved by
appending.  We do induction on x and y and case distinction on n and
m.

L184

(set-goal (pf "all x,y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))"))
; ?_1: all x,y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))

We work with following cases:
(1) x is Nil
  (1-1) y is Nil
  (1-2) y is Cons
    (1-2-1) y is L::y1
    (1-2-2) y is R::y1
      (1-2-2-1) n is Zero
      (1-2-2-2) n is Succ
(2) x is Cons
  (2-1) x is L::x1
  (2-2) x is R::x1
    (2-1-1) n is Zero
    (2-1-2) n is Succ

All subcases in (1-1) are done by auto at L189

(ind)
(ind)
(cases)
(cases)
(auto)
; ;   The active goal now is
; ?_5: all par3233,x3234(
;       all n,m(
;        Test n(Nil par) -> Test m x3234 -> Test(n+m)((Nil par)++x3234)) -> 
;       all n,m(
;        Test n(Nil par) -> 
;        Test m(par3233::x3234) -> Test(n+m)((Nil par)++(par3233::x3234)))) from
;   x3224  y3231

For (1-2) we also do the case analysis on the first element of Cons.
It results in (1-2-1) and (1-2-2)

L190

(ng)
; ok, the normalized goal is
; ?_10: all par3233,x3234(
;        all n,m(Test n(Nil par) -> Test m x3234 -> Test(n+m)x3234) -> 
;        all n,m(
;         Test n(Nil par) -> 
;         Test m(par3233::x3234) -> Test(n+m)(par3233::x3234))) from
;   x3224  y3231
(cases)
; ok, ?_10 can be obtained from
; ?_12: all x3234(
;        all n,m(Test n(Nil par) -> Test m x3234 -> Test(n+m)x3234) -> 
;        all n,m(Test n(Nil par) -> Test m(R::x3234) -> Test(n+m)(R::x3234))) from
;   x3224  y3231  par3244

; ?_11: all x3234(
;        all n,m(Test n(Nil par) -> Test m x3234 -> Test(n+m)x3234) -> 
;        all n,m(Test n(Nil par) -> Test m(L::x3234) -> Test(n+m)(L::x3234))) from
;   x3224  y3231  par3244

The formula for the case of L comes with induction hypotheses, and we
can prove it straightforwardly.

L192

(assume "y" "IHy")
(ng)
(assume "n" "m" "Hyp1" "Hyp2")
(use-with "IHy" (pt "n") (pt "Succ m") "Hyp1" "Hyp2")
; ok, ?_15 is proved.  The active goal now is
; ?_12: all x3234(
;        all n,m(Test n(Nil par) -> Test m x3234 -> Test(n+m)x3234) -> 
;        all n,m(Test n(Nil par) -> Test m(R::x3234) -> Test(n+m)(R::x3234))) from
;   x3224  y3231  par3244
(assume "y" "IHy" "n")
; ok, we now have the new goal 
; ?_16: all m(Test n(Nil par) -> Test m(R::y) -> Test(n+m)(R::y)) from
;   x3298  y3305  par3318  y  IHy:
;     all n,m(Test n(Nil par) -> Test m y -> Test(n+m)y)
;   n

L197 We do the case distinction on m which results in (1-2-2-1) and
(1-2-2-2).

(cases)
; ok, ?_16 can be obtained from
; ?_18: all n3483(
;        Test n(Nil par) -> 
;        Test(Succ n3483)(R::y) -> Test(n+Succ n3483)(R::y)) from
;   x3461  y3468  par3481  y  IHy:
;     all n,m(Test n(Nil par) -> Test m y -> Test(n+m)y)
;   n  m3484

; ?_17: Test n(Nil par) -> Test 0(R::y) -> Test(n+0)(R::y) from
;   x3461  y3468  par3481  y  IHy:
;     all n,m(Test n(Nil par) -> Test m y -> Test(n+m)y)
;   n  m3484
(assume "Hyp1" "Absurd")
; ok, we now have the new goal 
; ?_19: Test(n+0)(R::y) from
;   x3461  y3468  par3481  y  IHy:
;     all n,m(Test n(Nil par) -> Test m y -> Test(n+m)y)
;   n  m3484  Hyp1:Test n(Nil par)
;   Absurd:Test 0(R::y)

Now Absurd yields the falsity thanks to the computaion rule of Test.
Therefore, this can be solved by using Ex-Falso-Quodlibet.

L199

(use "Efq")
; ok, ?_19 can be obtained from
; ?_20: F from
;   x3461  y3468  par3481  y  IHy:
;     all n,m(Test n(Nil par) -> Test m y -> Test(n+m)y)
;   n  m3484  Hyp1:Test n(Nil par)
;   Absurd:Test 0(R::y)
(use "Absurd")
; ok, ?_20 is proved.  The active goal now is
; ?_18: all n3483(
;        Test n(Nil par) -> 
;        Test(Succ n3483)(R::y) -> Test(n+Succ n3483)(R::y)) from
;   x3461  y3468  par3481  y  IHy:
;     all n,m(Test n(Nil par) -> Test m y -> Test(n+m)y)
;   n  m3484

If m is Succ, it is an instance of the induction hypothesis IHy.

L202

(use "IHy")
; ok, ?_18 is proved.  The active goal now is
; ?_3: all par3463,x3464(
;       all y,n,m(Test n x3464 -> Test m y -> Test(n+m)(x3464++y)) -> 
;       all y,n,m(
;        Test n(par3463::x3464) -> 
;        Test m y -> Test(n+m)((par3463::x3464)++y))) from
;   x3461

Our next step is (2) x is Cons.  We prove (2-1) and (2-2) by the case
distinction on the first element of x.

L204

(cases)
; ok, ?_3 can be obtained from
; ?_22: all x3464(
;        all y,n,m(Test n x3464 -> Test m y -> Test(n+m)(x3464++y)) -> 
;        all y,n,m(Test n(R::x3464) -> Test m y -> Test(n+m)((R::x3464)++y))) from
;   x3461  par3500

; ?_21: all x3464(
;        all y,n,m(Test n x3464 -> Test m y -> Test(n+m)(x3464++y)) -> 
;        all y,n,m(Test n(L::x3464) -> Test m y -> Test(n+m)((L::x3464)++y))) from
;   x3461  par3500
(assume "x" "IHx")
; ok, we now have the new goal 
; ?_23: all y,n,m(Test n(L::x) -> Test m y -> Test(n+m)((L::x)++y)) from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))

By normalizing the goal the computation rule of Test is applied.

L206

(ng)
; ok, the normalized goal is
; ?_24: all y,n,m(Test(Succ n)x -> Test m y -> Test(Succ(n+m))(x++y)) from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))
(assume "y" "n" "m" "Hyp1" "Hyp2")
; ok, we now have the new goal 
; ?_25: Test(Succ(n+m))(x++y) from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))
;   y  n  m  Hyp1:Test(Succ n)x
;   Hyp2:Test m y

We instantiate IHx by letting y be y, n be Succ n, and m be m.  By
using Hyp1 and Hyp2 from the context, we obtain Test(Succ n+m)(x++y)
which is suitable to be the goal Test(Succ(n+m))(x++y).

L208

(use-with "IHx" (pt "y") (pt "Succ n") (pt "m") "Hyp1" "Hyp2")
; ok, ?_25 is proved.  The active goal now is
; ?_22: all x3464(
;        all y,n,m(Test n x3464 -> Test m y -> Test(n+m)(x3464++y)) -> 
;        all y,n,m(Test n(R::x3464) -> Test m y -> Test(n+m)((R::x3464)++y))) from
;   x3461  par3500
(assume "x" "IHx" "y")
; ok, we now have the new goal 
; ?_26: all n,m(Test n(R::x) -> Test m y -> Test(n+m)((R::x)++y)) from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))
;   y

For (2-2) we do the case distinction on n, and we have two cases
(2-2-1) and (2-2-2)

L210

(cases)
; ok, ?_26 can be obtained from
; ?_28: all n3502,m(
;        Test(Succ n3502)(R::x) -> Test m y -> Test(Succ n3502+m)((R::x)++y)) from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))
;   y  n3503

; ?_27: all m(Test 0(R::x) -> Test m y -> Test(0+m)((R::x)++y)) from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))
;   y  n3503

Test 0(R::x) is contradictory, hence (2-2-1) can be proven by
Ex-Falso-Quodlibet.

L211

(assume "m" "Absurd" "Hyp1")
; ok, we now have the new goal 
; ?_29: Test(0+m)((R::x)++y) from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))
;   y  n3503  m  Absurd:Test 0(R::x)
;   Hyp1:Test m y
(use "Efq")
; ok, ?_29 can be obtained from
; ?_30: F from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))
;   y  n3503  m  Absurd:Test 0(R::x)
;   Hyp1:Test m y
(use "Absurd")
; ok, ?_30 is proved.  The active goal now is
; ?_28: all n3502,m(
;        Test(Succ n3502)(R::x) -> Test m y -> Test(Succ n3502+m)((R::x)++y)) from
;   x3461  par3500  x  IHx:all y,n,m(Test n x -> Test m y -> Test(n+m)(x++y))
;   y  n3503

(2-2-2) is immediate from IHx

L214

(use "IHx")
; ok, ?_28 is proved.  Proof finished.
(save "TestProp")
; ok, TestProp has been added as a new theorem.

We prove the soundness and the completeness.  The statement of the
soundness is as follows: If u is in the grammer of U, Test 0 u is
True.

L219

(set-goal (pf "allnc u(U u -> Test 0 u)"))
; ?_1: allnc u(U u -> Test 0 u)
(assume "u" "IdHyp")
; ok, we now have the new goal 
; ?_2: Test 0 u from
;   {u}  IdHyp:U u

We apply the elimination axiom of U to the goal.  The competitor
predicate is substituted by {x | Test 0 x}, and the instantiated axiom
looks as follows:

allnc x(U x -> Test 0(Nil par) ->
              allnc x,y(U x -> U y -> Test 0 x -> Test 0 y -> Test 0(xLyR)) ->
        Test 0 x)

where xLyR is actually expressed with ++ and ::.

L221

(elim "IdHyp")
; ok, ?_2 can be obtained from
; ?_4: allnc x,y(U x -> U y -> Test 0 x -> Test 0 y -> Test 0(x++(L::y++R:))) from
;   {u}  IdHyp:U u

; ?_3: Test 0(Nil par) from
;   {u}  IdHyp:U u

The first one, Test 0 (Nil par), is trivial.

L222

(use "Truth-Axiom")
; ok, ?_3 is proved.  The active goal now is
; ?_4: allnc x,y(U x -> U y -> Test 0 x -> Test 0 y -> Test 0(x++(L::y++R:))) from
;   {u}  IdHyp:U u
(assume "x" "y" "U x" "U y" "Test 0 x" "Test 0 y")
; ok, we now have the new goal 
; ?_5: Test 0(x++(L::y++R:)) from
;   {u}  IdHyp:U u
;   {x}  {y}  U x:U x
;   U y:U y
;   Test 0 x:Test 0 x
;   Test 0 y:Test 0 y

Primarily we reduce the goal into Test 0 x and Test 0 L::y++R.  The
former one is immediate from the context.  The latter one is specified
by "?" to be a new goal after use-with.

L224

(use-with "TestProp" (pt "x") (pt "L::y++R:") (pt "0") (pt "0")
	  "Test 0 x" "?")
; ok, ?_5 can be obtained from
; ?_6: Test 0(L::y++R:) from
;   {u}  IdHyp:U u
;   {x}  {y}  U x:U x
;   U y:U y
;   Test 0 x:Test 0 x
;   Test 0 y:Test 0 y
(ng)
; ok, the normalized goal is
; ?_7: Test 1(y++R:) from
;   {u}  IdHyp:U u
;   {x}  {y}  U x:U x
;   U y:U y
;   Test 0 x:Test 0 x
;   Test 0 y:Test 0 y

Test 1 (y++R::) is reduced by TestProp as well, but we have Test 0 y
and trivially Test 1 R: holds.

L227

(use-with "TestProp" (pt "y") (pt "R:") (pt "0") (pt "1")
	  "Test 0 y" "Truth-Axiom")
; ok, ?_7 is proved.  Proof finished.
(save "Sound")
; ok, Sound has been added as a new theorem.

What we have to show for the completeness is the following: all x(Test
0 x -> S x) In order to do it, we prepare the following Parse Lemma:

all y allnc n,x(State n x -> allnc s(S s -> Test n y -> S(x++s++y)))

where State is an inductively defined predicate constant of arity
(nat, list par).

State 0 (Nil par)
allnc n,x,s(S s -> State n x -> State (Succ n) (x++s++L:))

Underlying idea is a shift-reduce syntax analyser.  We define a
shift-reduce machine equipping a stack of strings represented by
algState and a working memory for a string.  It starts with an empty
stack and a null string, and reads an input string of parentheses one
by one.  If the charactor to read is L, the shift operation works.
The current working memory is pushed to the stack and clear the
working memory by setting Nil.  We express it in the following
notation:

(stack, memory, input)
shift: (stack, s, L::x) -> (stack*(s,L), Nil, x)

* means that a string s is popped on the top of stack.

If the charactor to read is R, the reduce operation works.  It pops
the stack to take one string.  We call it by s1.  Let s be the current
working memory, and set s1++(L::s)++R to be the next string in the
working memory.

reduce: (stack*(s1,L),s,R::x) -> (stack,s1++(L::s)++R:,x)

The reduce operation fails if the stack is empty.  It matches our
intuition to read the parentheses; we see that the given string is
ill-formed if the number of Rs exceeds the one of Ls which we faced so
far from the left end of the string.

Roughly speaking, State n x holds if x is a string which has n
superfluous left parentheses and also the last charactor is not the
right parentheses.  In contrast, Test n y means that y is a string
which has n superfluous right parentheses.  For example, State n x and
Test n y implies S(x++y).  It is yielded as a special case of Parse
Lemma we will show later.

The statement of the Parse Lemma says that if s is in the grammar, x
opens n parentheses, and y closes n parentheses, x++s++y is in the
grammar.

By induction on y, we have to cases whether y is Nil or y is p::y'.

L248

(set-goal
 (pf "all y allnc n,x(State n x -> allnc s(S s -> Test n y -> S(x++s++y)))"))
; ?_1: all y allnc n,x(State n x -> allnc s(S s -> Test n y -> S(x++s++y)))
(ind)
; ok, ?_1 can be obtained from
; ?_3: all par3202,x3203(
;       allnc n,x(
;        State n x -> allnc s(S s -> Test n x3203 -> S(x++s++x3203))) -> 
;       allnc n,x(
;        State n x -> 
;        allnc s(S s -> Test n(par3202::x3203) -> S(x++s++(par3202::x3203))))) from
;   y3200

; ?_2: allnc n,x(
;       State n x -> allnc s(S s -> Test n(Nil par) -> S(x++s++(Nil par)))) from
;   y3200

In the case of Nil we apply the elimination axiom of State with taking
{n,x | allnc s(S s -> Test n(Nil par) -> S(x++s++(Nil par)))} for the
competitor predicate of State.

L253

(assume "n" "x" "IdHypState")
; ok, we now have the new goal 
; ?_4: allnc s(S s -> Test n(Nil par) -> S(x++s++(Nil par))) from
;   y3200  {n}  {x}  IdHypState:
;     State n x
(elim "IdHypState")
; ok, ?_4 can be obtained from
; ?_6: allnc n,x,s(
;       S s -> 
;       State n x -> 
;       allnc s(S s -> Test n(Nil par) -> S(x++s++(Nil par))) -> 
;       allnc s3211(
;        S s3211 -> Test(Succ n)(Nil par) -> S(x++s++L: ++s3211++(Nil par)))) from
;   y3200  {n}  {x}  IdHypState:
;     State n x

; ?_5: allnc s(S s -> Test 0(Nil par) -> S((Nil par)++s++(Nil par))) from
;   y3200  {n}  {x}  IdHypState:
;     State n x

The first subgoal is trivial since we assume S s and show S (Nil ++ s
++ Nil).  We simply use auto for it.  The second one is done by means
of Ex-Falso-Quodlibet because the premise contains Test(Succ n)(Nil
par) which is the falsity.

L257

(auto)
; ;   The active goal now is
; ?_6: allnc n,x,s(
;       S s -> 
;       State n x -> 
;       allnc s(S s -> Test n(Nil par) -> S(x++s++(Nil par))) -> 
;       allnc s3211(
;        S s3211 -> Test(Succ n)(Nil par) -> S(x++s++L: ++s3211++(Nil par)))) from
;   y3200  {n}  {x}  IdHypState:
;     State n x
(assume "n1" "x1" "s1" "H1" "H2" "H3" "s2" "H4" "Absurd")
; ok, we now have the new goal 
; ?_7: S(x1++s1++L: ++s2++(Nil par)) from
;   y3200  {n}  {x}  IdHypState:
;     State n x
;   {n1}  {x1}  {s1}  H1:S s1
;   H2:State n1 x1
;   H3:allnc s3215(S s3215 -> Test n1(Nil par) -> S(x1++s3215++(Nil par)))
;   {s2}  H4:S s2
;   Absurd:Test(Succ n1)(Nil par)
(use "Efq")
; ok, ?_7 can be obtained from
; ?_8: F from
;   y3200  {n}  {x}  IdHypState:
;     State n x
;   {n1}  {x1}  {s1}  H1:S s1
;   H2:State n1 x1
;   H3:allnc s3215(S s3215 -> Test n1(Nil par) -> S(x1++s3215++(Nil par)))
;   {s2}  H4:S s2
;   Absurd:Test(Succ n1)(Nil par)
(use "Absurd")
; ok, ?_8 is proved.  The active goal now is
; ?_3: all par3202,x3203(
;       allnc n,x(
;        State n x -> allnc s(S s -> Test n x3203 -> S(x++s++x3203))) -> 
;       allnc n,x(
;        State n x -> 
;        allnc s(S s -> Test n(par3202::x3203) -> S(x++s++(par3202::x3203))))) from
;   y3200

We proceed to the case y is p::y' with doing the case distinction on
p.

L264

(cases)
; ok, ?_3 can be obtained from
; ?_10: all x3203(
;        allnc n,x(
;         State n x -> allnc s(S s -> Test n x3203 -> S(x++s++x3203))) -> 
;        allnc n,x(
;         State n x -> 
;         allnc s(S s -> Test n(R::x3203) -> S(x++s++(R::x3203))))) from
;   y3200  par3228

; ?_9: all x3203(
;       allnc n,x(
;        State n x -> allnc s(S s -> Test n x3203 -> S(x++s++x3203))) -> 
;       allnc n,x(
;        State n x -> 
;        allnc s(S s -> Test n(L::x3203) -> S(x++s++(L::x3203))))) from
;   y3200  par3228

We prove the case of L. After assuming premises and normalizing the goal,
we apply the induction hypothesis on y to S(x++s++(L::y)).

L266

(assume "y" "IHy" "n" "x" "State n x" "s" "S s")
; ok, we now have the new goal 
; ?_11: Test n(L::y) -> S(x++s++(L::y)) from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
(ng)
; ok, the normalized goal is
; ?_12: Test(Succ n)y -> S(x++s++(L::y)) from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
(assume "Test(Succ n)y")
; ok, we now have the new goal 
; ?_13: S(x++s++(L::y)) from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
;   Test(Succ n)y:Test(Succ n)y
(use-with "IHy" (pt "Succ n") (pt "x++s++L:") "?" (pt "(Nil par)") "?" "?")
; ok, ?_13 can be obtained from
; ?_16: Test(Succ n)y from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
;   Test(Succ n)y:Test(Succ n)y

; ?_15: S(Nil par) from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
;   Test(Succ n)y:Test(Succ n)y

; ?_14: State(Succ n)(x++s++L:) from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
;   Test(Succ n)y:Test(Succ n)y

Each of three new subgoals are straightforwardly shown.
State(Succ n)(x++s++L:) comes from the second introduction axiom of State
and auto.

L270

(use "ApState")
; ok, ?_14 can be obtained from
; ?_18: State n x from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
;   Test(Succ n)y:Test(Succ n)y

; ?_17: S s from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
;   Test(Succ n)y:Test(Succ n)y
(auto)
; ;   The active goal now is
; ?_15: S(Nil par) from
;   y3182  par3210  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  State n x:State n x
;   {s}  S s:S s
;   Test(Succ n)y:Test(Succ n)y

The left two subgoals are immediate from auto as well.  For the case
of R, we apply the elimination axiom of State.

L273

(auto)
; ;   The active goal now is
; ?_10: all x3254(
;        allnc n,x(
;         State n x -> allnc s(S s -> Test n x3254 -> S(x++s++x3254))) -> 
;        allnc n,x(
;         State n x -> 
;         allnc s(S s -> Test n(R::x3254) -> S(x++s++(R::x3254))))) from
;   y3251  par3279
(assume "y" "IHy" "n" "x" "IdHypState")
; ok, we now have the new goal 
; ?_19: allnc s(S s -> Test n(R::y) -> S(x++s++(R::y))) from
;   y3251  par3279  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
(elim "IdHypState")
; ok, ?_19 can be obtained from
; ?_21: allnc n,x,s(
;        S s -> 
;        State n x -> 
;        allnc s(S s -> Test n(R::y) -> S(x++s++(R::y))) -> 
;        allnc s3306(
;         S s3306 -> Test(Succ n)(R::y) -> S(x++s++L: ++s3306++(R::y)))) from
;   y3251  par3279  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x

; ?_20: allnc s(S s -> Test 0(R::y) -> S((Nil par)++s++(R::y))) from
;   y3251  par3279  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x

For the case of State 0 (Nil par) is done by Ex-Falso-Quodlibet
because Test 0(R::y) in the premises is the falsity.

L280

(assume "s" "S s" "Absurd")
; ok, we now have the new goal 
; ?_22: S((Nil par)++s++(R::y)) from
;   y3251  par3279  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {s}  S s:S s
;   Absurd:Test 0(R::y)
(use "Efq")
; ok, ?_22 can be obtained from
; ?_23: F from
;   y3251  par3279  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {s}  S s:S s
;   Absurd:Test 0(R::y)
(use "Absurd")
; ok, ?_23 is proved.  The active goal now is
; ?_21: allnc n,x,s(
;        S s -> 
;        State n x -> 
;        allnc s(S s -> Test n(R::y) -> S(x++s++(R::y))) -> 
;        allnc s3306(
;         S s3306 -> Test(Succ n)(R::y) -> S(x++s++L: ++s3306++(R::y)))) from
;   y3251  par3279  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x

The case for p::x' is done by list operations.  After normalizing the
goal,

L285

(assume "n1" "x1" "s" "S s" "State n1 x1" "IH" "t" "S t" "Test n1 y")
; ok, we now have the new goal 
; ?_24: S(x1++s++L: ++t++(R::y)) from
;   y3251  par3279  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test(Succ n1)(R::y)
(ng)
; ok, the normalized goal is
; ?_25: S(x1++s++(L::t)++(R::y)) from
;   y3251  par3279  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

From this point, we work with arithmetic of list par.  We give
equations between list expressions in order to prove the goal.  Note
that ++ is left associative.

First we derive x1++s++(L::t)++(R::y) equals x1++s++(L::t)++R: ++y
because all x y, x++(R::y) = x++R: ++y

L287

(simp (pf "Equal(x1++s++(L::t)++(R::y))(x1++s++(L::t)++R: ++y)"))
; ok, Eq-Compat-Rev-list-par has been added as a new global assumption.
; ok, program constant cEqXxCompatXxRevXxlistXxpar: alpha83=>alpha83
; of t-degree 1 and arity 0 added
; warning: theorem cEqXxCompatXxRevXxlistXxparTotal stating totality missing
; ok, ?_25 can be obtained from
; ?_27: Equal(x1++s++(L::t)++(R::y))(x1++s++(L::t)++R: ++y) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

; ?_26: S(x1++s++(L::t)++R: ++y) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

S(x1++s++(L::t)++R: ++y) equals to S(x1++(s++(L::t))++R: ++y) because
x1++s++(L::t) = x1++(s++(L::t))

L288

(simp (pf "Equal(x1++s++(L::t))(x1++(s++(L::t)))"))
; ok, ?_26 can be obtained from
; ?_29: Equal(x1++s++(L::t))(x1++(s++(L::t))) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

; ?_28: S(x1++(s++(L::t))++R: ++y) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

S(x1++(s++(L::t))++R: ++y) implied from S(x1++(s++(L::t)++R:)++y)
since x1++(s++(L::t))++R: = x1++(s++(L::t)++R:).

L289

(simp (pf "Equal(x1++(s++(L::t))++R:)(x1++(s++(L::t)++R:))"))
; ok, ?_28 can be obtained from
; ?_31: Equal(x1++(s++(L::t))++R:)(x1++(s++(L::t)++R:)) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

; ?_30: S(x1++(s++(L::t)++R:)++y) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

We show S(x1++(s++(L::t)++R:)++y) from IHy.  For IHy, let n be n1 and
x be x1, apply State n1 x1, and let s be s++(L::t)++R:.  "?" is given
for S(s++(L::t)++R:) and Test n1 y to yield new goals.

L290

(use-with "IHy" (pt "n1") (pt "x1") "State n1 x1" (pt "s++(L::t)++R:") "?" "?")
; ok, ?_30 can be obtained from
; ?_33: Test n1 y from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

; ?_32: S(s++(L::t)++R:) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

S(s++(L::t)++R:) is reduced by ApS.  New goals are S s and
S((L::t)++R:).  The former one is trivial.  The second one, Test n1 y,
will be later.

L291

(simp (pf "Equal(s++(L::t)++R:)(s++((L::t)++R:))"))
; ok, ?_32 can be obtained from
; ?_35: Equal(s++(L::t)++R:)(s++((L::t)++R:)) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

; ?_34: S(s++((L::t)++R:)) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(use "ApS")
; ok, ?_34 can be obtained from
; ?_37: S((L::t)++R:) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

; ?_36: S s from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(auto)
; ;   The active goal now is
; ?_37: S((L::t)++R:) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

S t implies S((L::t)++R:)

L294

(use "ParS")
; ok, ?_37 can be obtained from
; ?_38: S t from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(auto)
; ;   The active goal now is
; ?_35: Equal(s++(L::t)++R:)(s++((L::t)++R:)) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

Now we manage equations which we assumed at L287,L288,L289, and L291.
Equal(s++(L::t)++R:)(s++((L::t)++R:)) is proven by the associativity
of appending and the reflexivity of the equation.  Test n1 y comes
from L290.  We have it in the context.

L296

(simp "ListAppdAssoc")
; ok, ?_35 can be obtained from
; ?_39: Equal(s++(L::t)++R:)(s++(L::t)++R:) from
;   y3089  par3117  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(use "Eq-Refl")
; ok, ?_39 is proved.  The active goal now is
; ?_33: Test n1 y from
;   y3089  par3117  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(auto)
; ;   The active goal now is
; ?_31: Equal(x1++(s++(L::t))++R:)(x1++(s++(L::t)++R:)) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

This equation comes from the associativity and the realexivity.

L299

(simp "ListAppdAssoc")
; ok, ?_31 can be obtained from
; ?_40: Equal(x1++s++(L::t)++R:)(x1++(s++(L::t)++R:)) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(simp "ListAppdAssoc")
; ok, ?_40 can be obtained from
; ?_41: Equal(x1++s++(L::t)++R:)(x1++(s++(L::t))++R:) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(simp "ListAppdAssoc")
; ok, ?_41 can be obtained from
; ?_42: Equal(x1++s++(L::t)++R:)(x1++s++(L::t)++R:) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(use "Eq-Refl")
; ok, ?_42 is proved.  The active goal now is
; ?_29: Equal(x1++s++(L::t))(x1++(s++(L::t))) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y

The last one is also from the associativity and the reflexivity.

L303

(simp "ListAppdAssoc")
; ok, ?_29 can be obtained from
; ?_43: Equal(x1++s++(L::t))(x1++s++(L::t)) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(use "Eq-Refl")
; ok, ?_43 is proved.  The active goal now is
; ?_27: Equal(x1++s++(L::t)++(R::y))(x1++s++(L::t)++R: ++y) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(ng)
; ok, the normalized goal is
; ?_44: Equal(x1++s++(L::t)++(R::y))(x1++s++(L::t)++(R::y)) from
;   y3151  par3179  y  IHy:allnc n,x(State n x -> 
;                           allnc s(S s -> Test n y -> S(x++s++y)))
;   {n}  {x}  IdHypState:State n x
;   {n1}  {x1}  {s}  S s:S s
;   State n1 x1:State n1 x1
;   IH:allnc s(S s -> Test n1(R::y) -> S(x1++s++(R::y)))
;   {t}  S t:S t
;   Test n1 y:Test n1 y
(use "Eq-Refl")
; ok, ?_44 is proved.  Proof finished.

We save this formula by Parse.

L308

(save "Parse")
; ok, Parse has been added as a new theorem.
; ok, program constant cParse: list par=>algState=>algS=>algS
; of t-degree 0 and arity 0 added

The completeness is immediate from Parse.  We assume x and Test 0 x.

L311

(set-goal (pf "all x(Test 0 x -> S x)"))
; ?_1: all x(Test 0 x -> S x)
(assume "x" "Test 0 x")
; ok, we now have the new goal 
; ?_2: S x from
;   x  Test 0 x:Test 0 x

Applying an instantiated Parse to this goal.  In Parse let y be x, n
be 0, and x be (Nil par), then we have State 0 (Nil par) -> allnc s(S
s -> Test 0 x -> S((Nil par)++s++x))

Moreover, taking InitState for State 0 (Nil par) and letting s be (Nil
par),

S (Nil par) -> Test 0 x -> S((Nil par)++(Nil par)++x)

is yielded.  We obtain the goal S x due to noemalizing term after
providing S (Nil par) and Test 0 x which are trivial.

L313

(use-with "Parse" (pt "x") (pt "0") (pt "(Nil par)")
	  "InitState" (pt "(Nil par)") "InitS" "Test 0 x")
; ok, ?_2 is proved.  Proof finished.
(save "Complete")
; ok, Complete has been added as a new theorem.
; ok, program constant cComplete: list par=>algS
; of t-degree 0 and arity 0 added

We gave InitState and InitS in the above proof.  From the viewpoint of
our shift-reduce machine, they are used to specify the initial state
of the machine, namely the empty stack and the vacant working memory.
We prepare one corollary to make examples.

L319

(set-goal (pf "all x ex p((p -> S x) & ((p -> F) -> S x -> F))"))
; ?_1: all x ex p((p -> S x) & ((p -> F) -> S x -> F))
(assume "x")
; ok, we now have the new goal 
; ?_2: ex p((p -> S x) & ((p -> F) -> S x -> F)) from
;   x

ex-intro is the introduction of the existential quantifier.  We give
Test 0 x to be the instance of p.

L321

(ex-intro (pt "Test 0 x"))
; ok, ?_2 can be obtained from
; ?_3: (Test 0 x -> S x) & ((Test 0 x -> F) -> S x -> F) from
;   x

We should prove the both sides of the conjunction.  split works for
the introduction of conjunction.

L322

(split)
; ok, we now have the new goals 
; ?_5: (Test 0 x -> F) -> S x -> F from
;   x

; ?_4: Test 0 x -> S x from
;   x

This goal is immediate from Complete.  The other goal is done by the
soundness.

L323

(use "Complete")
; ok, ?_4 is proved.  The active goal now is
; ?_5: (Test 0 x -> F) -> S x -> F from
;   x
(assume "Test 0 x -> F" "S x")
; ok, we now have the new goal 
; ?_6: F from
;   x  Test 0 x -> F:Test 0 x -> F
;   S x:S x
(use "Test 0 x -> F")
; ok, ?_6 can be obtained from
; ?_7: Test 0 x from
;   x  Test 0 x -> F:Test 0 x -> F
;   S x:S x
(use "Sound")
; ok, ?_7 can be obtained from
; ?_8: U x from
;   x  Test 0 x -> F:Test 0 x -> F
;   S x:S x

This is immediate from SU since we have S x.

L327

(use "SU")
; ok, ?_8 can be obtained from
; ?_9: S x from
;   x  Test 0 x -> F:Test 0 x -> F
;   S x:S x
(auto)
; ; Proof finished.
(save "CompleteSound")
; ok, CompleteSound has been added as a new theorem.
; ok, program constant cCompleteSound: list par=>boole@@algS
; of t-degree 0 and arity 0 added

All necessary lemmas SU, Parse, and Complete should be animated for
the computation.  We also add variable names st of type algState and f
of type algState=>algS=>algS to give a nicer displaying.  Our
extracted program from CompleteSound looks as follows:

L338

(define parser-term
  (nt (proof-to-extracted-term (theorem-name-to-proof "CompleteSound"))))
(pp parser-term)
; [x0]
;  Test 0 x0@
;  (Rec list par=>algState=>algS=>algS)x0([st1,b2][if st1 b2 ([b3,st4]cInitS)])
;  ([par1,x2,f3,st4,b5]
;    [if par1
;      (f3(cApState b5 st4)cInitS)
;      [if st4 cInitS ([b6,st7]f3 st7(cApS b6(cParS b5)))]])
;  cInitState 
;  cInitS

The extracted term from CompleteSound computes two things.  Whether
the given string follows the grammar, and the representation of the
result of the syntax analize in a constructor expression in algS.  If
the input is ill-formed, the second part of the result is cInitS.

L354

(pp (nt (mk-term-in-app-form parser-term (pt "L::R:"))))
"True@cApS cInitS(cParS cInitS)"

(pp (nt (mk-term-in-app-form parser-term (pt "R::L:"))))
"False@cInitS"

(pp (nt (mk-term-in-app-form parser-term (pt "L::R::L::R:"))))
"True@cApS(cApS cInitS(cParS cInitS))(cParS cInitS)"

(pp (nt (mk-term-in-app-form parser-term (pt "L::L::R::R:"))))
"True@cApS cInitS(cParS(cApS cInitS(cParS cInitS)))"
