STACK provides libraries to represent and manage lines of a text-based proof in a tree structure. This page is reference documentation for these CAS libraries. For examples of how to use these see the topics page on using [Parson's problems](../Topics/Parsons.md).
To use these functions you have to [load an optional library](../Authoring/Inclusions.md) into each question.
E.g. `stack_include_contrib("prooflib.mac")` will include the library published in the master branch on github, which will be at or just ahead of an official release.
## Proof construction functions, and their manipulation
Proofs are represented as "proof construction functions" with arguments. For example, an if and only if proof would be represented as `proof_iff(A,B)`, where both `A` and `B` are sub-proofs. Proof construction functions don't typically modify their arguments, but some proof construction functions have simplification properties. For example `proof_iff(A,B)` is normally equivalent to `proof_iff(B,A)`.
...
...
@@ -10,6 +14,7 @@ STACK supports the following types of proof construction functions. The followi
*`proof()`: general, unspecified proof.
*`proof_c()`: general proof, with commutative arguments. Typically each argument will be another proof block type.
*`proof_opt()`: steps in a proof which are optional. It assumes a single step. Wrap each optional step individually.
The following represent particular types of proof.
do (p1:p2, p2:proof_one_distrib(p1), if is(p1=p2) then return(proof_ensure_list(p2)))
do (p1:p2, p2:proof_one_distrib(p1), if is(p1=p2) then return(map(proof_remove_nullproof, proof_ensure_list(p2))))
);
proof_one_alternatives(pr) := block(
if atom(pr) then return(pr),
if proof_commutep(pr) then return(apply(pf_one, map(lambda([ex], apply(op(pr), map(proof_one_alternatives, ex))), listify(permutations(args(pr)))))),
/* In a proof by exhaustive cases the first element is fixed. */
if op(pr)=proof_opt then return(pf_one(first(pr), nullproof)),
/* In a proof by exhaustive cases the first element is fixed. */
if op(pr)=proof_cases then return(apply(pf_one, map(lambda([ex], apply(op(pr), append([first(args(pr))], map(proof_one_alternatives, ex)))), listify(permutations(rest(args(pr))))))),
/* In a proof by induction cases the first element and last elents are fixed. */
if op(pr) = proof_ind then return(apply(pf_one, map(lambda([ex], apply(op(pr), append([first(args(pr))],