1 /* Proves and Test for "parGosper" and "Gosper" */
2 /* by Fabrizio Caruso */
6 /* It proves the result of Gosper's algorithm */
8 /* Remark: The level of verbosity depends on "gs_prove_detail" */
10 gs_prove(expr,k,cert) :=
13 if expr = NON_HYPERGEOMETRIC then
15 if gs_prove_detail>= PROOF_LOW then
17 print("The input is not hypergeometric in ", k),
18 print("There is no proof for this case.")
23 if expr = NO_HYP_SOL then
25 if gs_prove_detail>=PROOF_LOW then
27 print("Gosper's algorithn found that"),
28 print("there is no hypergemetric antidifference for ", expr),
29 print("There is no proof for this case.")
35 if gs_prove_detail>=PROOF_MEDIUM then
37 print("Gosper's algorithm found the antidifference: ", cert*expr),
38 print("This means we must have: "),
39 print(expr, " = ", subst(k+1,k,cert*expr)-cert*expr),
40 print("which can be proved by dividing both members by ", expr),
41 print("and checking the resulting equality between rational functions")
43 rhs : shiftQuo(expr,k)*subst(k+1,k,cert)-cert,
44 if gs_prove_detail>=PROOF_HIGH then
49 return(is(1=factor(xthru(rhs))))
54 /* Routines related to the proof writer for Zeilberger's algorithm */
56 zb_meaning(zb_in,k,n,zb_cert,zb_rec) :=
59 print(sum(zb_rec[j__]*subst(n+j__-1,n,zb_in),j__,1,length(zb_rec))," = "),
60 print(subst(k+1,k,zb_cert*zb_in)-zb_cert*zb_in,";")
63 zb_reduced_meaning(zb_in,k,n,zb_cert,zb_rec) :=
66 return([sum(zb_rec[j__]*product(subst(n+i__-1,n,shiftQuo(zb_in,n)),i__,1,j__-1),j__,1,length(zb_rec)),
67 subst(k+1,k,zb_cert)*shiftQuo(zb_in,k)-zb_cert])
70 zb_test_equalityAux(eq_pair) :=
73 lhs : rat(eq_pair[1]),
74 rhs : rat(eq_pair[2]),
83 zb_test_equality(eq_pair) :=
86 test_res : zb_test_equalityAux(eq_pair),
87 if test_res = true then
91 if zb_prove_detail>=PROOF_LOW then
93 print("lhs : ", test_res[1]),
94 print("rhs : ", test_res[2])
102 /* It proves the result of Zeilbeger's algorithm */
104 /* The level of verbosity depends on "zb_prove_detail" */
106 /* zb_prove(zb_in,k,n,zb_out) := */
108 block([i,j,zb_red,zb_in,zb_out,proof,undecided,k,n],
112 if length(args)=3 then
114 zb_out:Zeilberger(zb_in,k,n)
120 if length(zb_out) = 0 then
122 if zb_prove_detail>=PROOF_LOW then
124 print("Zeilberger's algorithm could not find a recurrence for the given order."),
125 print("This DOES NOT mean that such a recurrence with the given order does not exist."),
126 print("Zeilberger's algorithm DOES NOT always find the minimal order recurrence"),
127 print("but it will find a recurrence for a higher order if a recurrence exists."),
128 print("Suggestion: "),
129 print("Sometimes rewriting the summand can produce a lower order recurrence."),
130 print("There is no proof for this case.")
136 if zb_out=[NON_PROPER_HYPERGEOMETRIC] then
138 if zb_prove_detail>= PROOF_LOW then
140 print(zb_in, " is not proper hypergeometric in ", n, " and ", k),
141 print("There is no proof for this case.")
146 if length(zb_out) = 1 then
148 if zb_prove_detail>=PROOF_MEDIUM then
150 print("The result contains one recurrence for ", zb_in, ": "),
152 zb_meaning(zb_in,k,n,zb_out[1][1],zb_out[1][2]),
154 print("which we can prove by dividing both members of the equality by ", zb_in),
155 print("and checking the resulting equality between rational functions.")
157 zb_red : zb_reduced_meaning(zb_in,k,n,zb_out[1][1],zb_out[1][2]),
158 if zb_prove_detail>= PROOF_HIGH then
160 print("Namely it is equivalent to test the equality between: "),
162 print(zb_red[1], " and ", zb_red[2]),
166 return(zb_test_equality(zb_red))
171 print("The result contains ", length(zb_out),
172 " recurrences for ", zb_in, ": "),
174 for i : 1 thru length(zb_out) do
176 if zb_prove_detail>=PROOF_MEDIUM then
179 zb_meaning(zb_in,k,n,zb_out[i][1],zb_out[i][2]),
181 print("which we can proved by dividing both members of the equality by ", zb_in),
182 print("and checking the resulting equality between rational functions.")
185 zb_red : zb_reduced_meaning(zb_in,k,n,zb_out[1][1],zb_out[1][2]),
188 if zb_prove_detail >= PROOF_HIGH then
190 print("Namely it is equivalent to test the equality between: "),
191 print(zb_red[1], " and ", zb_red[2]),
194 if(zb_test_equality(zb_red)) then
195 print("which has been tested to be true")
198 print("which has been tested to be FALSE!!!"),
201 print("------------------------------------------------------------------------")
209 /* It tests the result of "parGosper" */
210 /* As input it takes a list of quadruples of the form : */
211 /* [hypergeometric term, summation variable, recurrence variable, recurrence order] */
213 /* Remark: The level of verbosity is decided by the value of "zb_prove_detail" */
216 block([i,res,zb_prove_res,zb_res],
219 if zb_prove_detail >= PROOF_LOW then
220 print("This benchmark contains : ", length(test_set), " elements"),
221 for i : 1 thru length(test_set) do
223 if zb_prove_detail>= PROOF_LOW then
226 print("computing the solution...")
228 zb_res : parGosper(test_set[i][1],
229 test_set[i][2],test_set[i][3],
232 if zb_prove_detail >= PROOF_LOW then
236 if zb_res = [NON_PROPER_HYPERGEOMETRIC] then
237 print("the input is not hypergeometric")
239 print("non-empty solution found"),
241 if zb_prove_detail >= PROOF_LOW then
242 print("checking the solution..."),
243 zb_prove_res : zb_prove(test_set[i][1],test_set[i][2],test_set[i][3],zb_res),
244 res : endcons(zb_prove_res,res),
247 if zb_prove_detail >= PROOF_LOW then
253 if zb_prove_detail >= PROOF_LOW then
254 print("test failed!")
256 print("---------------------------------------------------------------")
258 if apply("and",res) then
260 if zb_prove_detail>= PROOF_LOW then
261 print("all tests passed"),
266 if zb_prove_detail>= PROOF_LOW then
267 print("some test was not passed!"),