BNF Syntax of Prolog
Dr .Richard Botting CSUSB
 
The syntax of Prolog is deceptively simple.  The User inputs a
series of predicates that have three different meanings - facts
to be stored, search goals or questions of the current facts, commands
which do one thing.  There is also a special kind of rule called
a clause which defines conditions underwhich a fact can be true.

	fact::=clause ".",
	clause::=predicate":-"predicate.

	query::=goal.
	goal::="?-" predicate"." | predicate "?",

	command::="!-" predicate"." | predicate "!".
Notice the periods and other punctuators!
The second alternative form of query and command is used in our UNSW Prolog
only.

	predicate::=structure,
	structure::=prefix argument | argumument postfix | argument infix argument | functor"(" argument #("," argument)")" | functor.
	argument::=constant | variable | structure,
	constant::= number | string | word #("_" word),
	variable::= ("_"|"A".."Z")#(letters|digits|"_").
A functor is a non-numeric constant that is written as if it was a
function.   It is called a funct_or because it is just a formula and
may never be evaluated - it is just a way to label the kind of
structure involved:
	married(X, wife(X)).
	married(husband(X),X).
Are both facts that can apear in the Prolog data base but there is no
need to define what wife(X) and husband(Y) actually are...  Prolog normally
will not match wife(X) with any structure that doesn't have 'wife' in front:
	married(dick, tricia)?
	*No

	functor::=word #("_" word) | "infix" infix | "prefix" prefix | "postfix" postfix.
	
Some commands interpret some of the structures in special ways.  For example,
A predicate input as a fact is stored as piece of data, but input as a
command or goal it becomes a call to a procedure.  A clause is also
stored by Prolog but then it can act as a subprogram that
can be called as a command, or as part of another command.

. SPECIAL EXAMPLES OF GENERAL SYNTAX
 
append_statement ::= "append(" list "," list "," list")",
 
consult_statement ::= "consult(" filename ")",
 
reconsult_statement ::= "reconsult(" filename ")",
 
var_statement ::= "var(" structure ")",
 
nonvar_statement ::= "nonvar(" structure ")"
 
atom_statement ::= "atom(" structure ")",
 
atomic_statement ::= "atomic(" structure ")",
 
integer_statement ::= "integer(" structure ")",
 
listing_statement ::= "listing(" atom ")",
 
clause_statement ::= "clause(" goal ")",
 
asserta_statement ::= "asserta(" goal ")",
 
assertz_statement ::= "assertz(" goal ")",
 
loop::structure=`repeat; body_of_loop; fail`.
repeat_statement ::= "repeat",
 
not_statement ::= "not(" goal ")",
 
see_statement ::= "see(" input_file ")",
 
seeing_statement ::= "seeing(" input_file ")",
 
seen_statement ::= "seen(" input_file ")",
 
tell_statement ::= "tell(" output_file ")",
 
telling_statement ::= "telling(" output_file ")",
 
told_statement ::= "told(" output_file ")",
 
assignment_statement ::= variable "is" expression,
 
trace_statement ::= "trace",
 
spy_p_statement ::= "spy p",
 
 
SYNTAX
 
operator ::= "+" | "-" | "*" | "/" | "mod" | "is" | user_defined_operator,
 
term ::= constant | variable | compound_term,
 
constant ::= integer | atom,
 
atom ::= character | sequence_of_characters,
 
anonymous_variable ::= "_",
 
compound_term ::= functor "(" term #("," term)")" | functor 
	| prefix_operation | list |postfix_operation|infix_operation,
functor::=atom,
 
Associated with each functor in a compound term is the number of 
arguments it has.  This is called its arity([sic] "arity"). An atom can 
different definitions for different arities.  
 
list ::= "["compound_term #("," compound_term) "]" | "[" "]",
 
program ::= sentence  #( ". " sentences),
 
sentence ::= head sentence_body,
 
sentence_head ::= ( | goal),
 
sentence_body ::= #goal,
 
non_unit_clause ::= head_goal ":-" ( | #goal),
 
goal ::=compund_term, 

unit_clause ::= head_goal,
 
query ::= #(goal ",") goal "?" | ":-" goal #("," goal) ".",
 
directive ::= #(goal ",") goal "!",
 
prefix_operation ::= prefix_operator goal,
 
postfix_operator ::= goal postfix_operator,
 
infix_operation ::= goal infix_operator goal,