This document provides information on using the predicates exported from the syntax module. It assumes the user has a strong grasp of Prolog logic programming, including using operators defined by the op/3 directive and Definite Clause Grammars (DCG).
The syntax module provides the primitive logical connectives defined in Principia Mathematica,1 and, as such, provides the user a facility to translate mathematical proofs into executable code simply and correctly. Users familiar with (or practitioners of) Mathematical Philosophy2 should feel right at home with the operators exported from the syntax module.
Practically speaking, the syntax module provides fundamental consequence connectives used by the set_utils module and other modules. Its operators are similar to ones provided by other logic framework programming languages.3
This module exports no predicates.
The syntax module exports the following operators (n.b.: the using module must (re)declare the operator syntax):
| Synopsis: | +GoalA sinon +GoalB [MOD] | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Arguments: |
| |||||||||||||||
| Declaration: | :- op(1100, xfy, sinon). | |||||||||||||||
| Description: | sinon/[2,4] permits two proofs to be essayed consectively -- it's very much in the syntactic/semantic vein of ';'/[2,4], except that the order is deterministic for sinon/[2,4] (fr: 'if not') whereas 'GoalA; GoalB'/[2,4]'s order is not by nature fixed (I've observed situations where GoalB, usually the more general case, being executed first, leading to unintented results). This predicate is short-circuiting: if GoalA is true, GoalB is not pursued. | |||||||||||||||
| Truth table: |
| |||||||||||||||
| Backtracking: | Much like ';'/[2,4]. More specifically, all proofs for GoalA are exhausted first before attempting GoalB | |||||||||||||||
| Examples: | This operator has proved to be useful for dealing with unexpected values:
It can be used to assign a default as well:
Or, and this is a common pattern for throughout various systems, log a troublesome (but not terminal) event:
| |||||||||||||||
| See Also: | ';'/[2,4] try/[1,3] | |||||||||||||||
| Synopsis: | try +Goal [MOD] | ||||||
|---|---|---|---|---|---|---|---|
| Arguments: |
| ||||||
| Declaration: | :- op(200, fx, try). | ||||||
| Description: | try/[1,3] is really a derivative sinon/[2,4]: (try X) = (X sinon true). 'try Goal' calls Goal and simply succeeds, even if goal fails, preventing (some would say: 'subverting') bactracking over an establish proof branch. | ||||||
| Truth table: |
| ||||||
| Backtracking: | All proofs for Goal are attempted | ||||||
| Examples: | This predicate is excellent for protecting an established state from a predicate one wishes to essay but not have backtrack if it fails:
| ||||||
| See Also: | sinon/[2,4] | ||||||
| Synopsis: | ~ +Goal (pron:"not" Goal) [MOD] | ||||||
|---|---|---|---|---|---|---|---|
| Arguments: |
| ||||||
| Declaration: | :- op(900, fy, ~). | ||||||
| Description: | Ever try to explain why \+/1 ('for every') means 'not' and not look stupid while 'explaining' the concept? It's very, very hard, especially given the somewhat different meaning of \+ in mathematics ... so, as a face-saving measure I propose the following reasonable alternative: ~/1. Would a DCG version of '~Goal' make any sense? | ||||||
| Truth table: |
| ||||||
| Backtracking: | As for not/1 and \+/1. | ||||||
| Examples: | The below example is true if S0 and S1 do not unify:
Besides the standard usage (negation or complement), ~/1 can be doubled particularly to see if two things can be unified without changing the modality (this prevents free variables from being unintentionally bound):
The above code prepends the Driver to the DCG if Address is in Addresses. If Address is a free variable, it remains free, or if there is a free variable in Addresses, that free variable in Addresses is also unchanged. | ||||||
| See Also: | not/1 \+/1 | ||||||
| Synopsis: | +GoalA /\ +GoalB (pron: GoalA "and" GoalB) [MOD] | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Arguments: |
| |||||||||||||||
| Declaration: | :- op(500, yfx, /\). | |||||||||||||||
| Description: | A semantic equivalent to ','/2; convenient for expressing mathematical proofs. | |||||||||||||||
| Truth table: |
|
|||||||||||||||
| Backtracking: | As for ','/2. | |||||||||||||||
| Examples: | A common pattern in the unit test framework is to test that a predicate gives a true (i.e. smaller) subset of the input data:
The above statement asserts that Actual is smaller than Sales. In plain language: "All the elements of Actual are in Sales, AND there exists an X such that it is in Sales but not in Actual". Literally: "X is in Actual implies X is in Sales, AND not X is in Actuals is implied by X is in Sales." | |||||||||||||||
| See Also: | ','/2 | |||||||||||||||
| Synopsis: | +GoalA \/ +GoalB (pron: GoalA "or" GoalB) [MOD] | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Arguments: |
| |||||||||||||||
| Declaration: | :- op(500, yfx, \/). | |||||||||||||||
| Description: | A semantic equivalent to ';'/2; convenient for expressing mathematical proofs. | |||||||||||||||
| Truth table: |
| |||||||||||||||
| Backtracking: | As for ';'/2. | |||||||||||||||
| Examples: | Currently only the syntax module itself uses \//2; a derivative example is: | |||||||||||||||
| See Also: | ';'/2 | |||||||||||||||
| Synopsis: | ?Element <- ?List (pron: Element "is in" List) | ||||||
|---|---|---|---|---|---|---|---|
| Arguments: |
| ||||||
| Declaration: | :- op(200, yfx, <-). | ||||||
| Description: | A semantic equivalent to basics:member/2 that follows mathematic convention. | ||||||
| Backtracking: | As for basics:member/2. | ||||||
| Examples: | Many rule findings reduce to confirming the known information contains a particular type:
But, of course, <- provides a convenient way of extracting information buried in context: | ||||||
| See Also: | basics:member/2 |
| Synopsis: | +GoalA => +GoalB (pron: GoalA "implies" GoalB) [MOD] | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Arguments: |
| |||||||||||||||
| Declaration: | :- op(920, xfy, =>). | |||||||||||||||
| Description: | Implication. Usually, in propositional logic one uses implication to relate a body of conjuctive clauses to a consequence. This operator is provided if it is not necessary to define a rule (in this case, one simply wishes to use implication "anonymously"). N.B.: | |||||||||||||||
| Truth table: |
|
|||||||||||||||
| Backtracking: | As for ':-'/2. | |||||||||||||||
| Examples: | =>/2 provides a compact way to embed mini-rule-like assertions into rule findings (without needing to take the extra step of defining these assertions as rules explicitly):
We are saying that "if we can find Distant in the GreateDistances list, then MinDistance must be less than or equal to that Distance" or "All 'Distance's in GreaterDistances are greater than MinDistance". | |||||||||||||||
| See Also: | '<='/2 '<=>'/2 ':-'/2 | |||||||||||||||
| Synopsis: | +GoalA <= +GoalB (pron: GoalA "is implied by" GoalB) [MOD] | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Arguments: |
| |||||||||||||||
| Declaration: | :- op(920, xfy, <=). | |||||||||||||||
| Description: | Reverse implication. Actually, this operator, as opposed to =>, bears the closest resemblance to ':-'/2. As such, there are many practical applications of this operator when developing rules for (e.g.) expert systems. N.B.: N.B.: N.B.: | |||||||||||||||
| Truth table: |
|
|||||||||||||||
| Backtracking: | As for ':-'/2. | |||||||||||||||
| Examples: | The unit test framework to validate a proper subset relation between two sets:
The above example ensures 'Actual' is a subset and smaller than 'CLOB'. | |||||||||||||||
| See Also: | '=>'/2 '<=>'/2 ':-'/2 | |||||||||||||||
| Synopsis: | +GoalA <=> +GoalB (pron: GoalA "if, and only if," GoalB, or GoalA "implies" GoalB, "and vice versa") [MOD] | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Arguments: |
| |||||||||||||||
| Declaration: | :- op(920, xfy, <=>). | |||||||||||||||
| Description: | Double implication, or mutually-dependent implication. The following pattern ...
... in logic programming is so common that it has been replaced with the equivalent statement:
| |||||||||||||||
| Truth table: |
|
|||||||||||||||
| Backtracking: | Actually, backtracking for <=>/2 is a subtle and beautiful thing,6 not only are all the possibilities explored where both GoalA and GoalB are true, but 'GoalA <=> GoalB' is also true where both GoalA and GoalB fail. This can be a rather frightening prospect to consider, but this issue is mitigated in that this op is most often used in the very restricted domain of comparing two fully-instantiated and finite sets. In this domain, then, backtracking through <=>/2 is not a matter of concern. | |||||||||||||||
| Examples: | Expert systems sometimes operate on the principle of accumulating rule findings to reach a conclusion. One could write a unit test that ensures the new information is added when findings occur:
More complex examples present themselves in the set_utils module, which has a foundation in the syntax of the predicate calculus implemented in this module. | |||||||||||||||
| 1 | More specifically, the logical connectives that form the miminal, useful, set of logical operators use by Gödel in "Über formal unentscheidbare Sätze der Principia Mathematica und verwandter Systeme" (trans: "On Formally Undecidable Propositions of Principia Mathematica and Related Systems"). See e.g.: [NNH2001], p. 70, table 2. |
| 2 | Bertrand Russell laid out the work of a mathematical philosopher in [Rus1919]; a wonderful little book that serves as a prologue to the Principia Mathematica. |
| 3 | The Mercury programming language provided the precedences for the operators defined here. See [Merc], Syntax chapter, § Builtin Operators. |
| 4 | One could amuse oneself with idle speculation: did the person who implemented the infix if/2 statement made so popular in Perl attempt to introduce a modicum of logic into the mess that is imperative programming, e.g.:
but that would be quite a stretch, and, besides, one has other things to do, like write more documentation, than to engage in such frivolity. Ah, well! |
| 5 | |
| 6 | As is backtracking in general, it is just that backtracking for <=>/2 is subtle and beautiful to a greater extent. |
| [Merc] | Mercury Language Reference Manual, Version 0.11.0, Fergus Henderson, Thomas Conway, Zoltan Somogyi, David Jeffery, Peter Schachte, Simon Taylor, Chris Speirs, Tyson Dowd, Ralph Becket, University of Melbourne (Australia, not Florida), http://www.cs.mu.oz.au/research/mercury. No date of publication given. |
| [NNH2001] | Gödel's Proof (Revised Edition), Ernest Nagel and James R. Newman, edited and with a new foreward by Douglas R. Hofstadter, New York University Press, NY, 2001. |
| [Rus1919] | Introduction to Mathematical Philosophy, Bertrand Russell, Dover Publications, Inc., NY, 1993. |
| [SOC1997] | Learning Perl on Win32 Systems, Randal L. Schwartz, Erik Olson, Tom Christiansen, O'Reilly and Associates, Inc., Sebastopol, CA. 1997. |
| author: | Douglas M. Auclair (dauclair at hotmail dot com) |
|---|---|
| date: | December 15, 2005 |
| Copyright © 2005, Cotillion Group, Inc. All rights reserved. | |