/* ATNC.PL */ :- reconsult( 'atncommon.pl' ). /* Introduction. ------------- This file defines predicates that depend on the internal representation of ATNs. ATNCOMMON.PL defines the representation-independent predicates. Interface representation of ATNs (the 'expanded form'). ------------------------------------------------------- The interface between the two files is the representation of a node and its body and arcs as a structure: atn( Node, Command, Arcs ) Here, Node is the original node term; Command is the original command, as a Prolog goal ('true' if there was no command); and Arcs is a list of the form [ Cond1, Node1, Cond2, Node2, ... CondN, NodeN ] which defines the arcs. The conditions are Prolog goals: the final one (CondN) is always 'true'. If the original ATN had no default arc, the final one (NodeN) is 'failure'. So the definition count(N) :: Rem is (N mod 2) to odd(N) if Rem=0 to even(N). becomes atn( count(N), (Rem is (N mod 2)), [ Rem=0, odd(N), true, even(N) ] ). Note that this representation is _not_ the same as the internal representation used when interpreting ATNs. Exported predicates. -------------------- This file exports: do_node( Node ) assert_expanded_atn( Expanded_ATN ) retractall_expanded_atn( Node ) 'do_node' is for the user. Call it with a node as argument to start executing an ATN. 'assert_expanded_atn' and 'retractall_expanded_atn' are for the loading routines in ATNCOMMON.PL. 'assert_expanded_atn' converts to internal form and asserts the ATN. 'retractall_expanded_atn' retracts all nodes matching its argument. Internal representation of ATNs. -------------------------------- In this file, ATNs are represented as clauses for the predicate '$node'. '$node' has two arguments. The first is the name of the node to be entered. The second will be instantiated to the next node. Clauses contain a tail which obeys the command and selects the next node. The clause for the node shown above would be '$node'( count(N), Next ) :- Rem is (N mod 2), ( Rem=0 -> Next = odd(N) ; Next = even(N) ). */ /* The interpreter. ---------------- The main predicate is do_node( Node+ ). It starts executing an ATN at Node, and fails or succeeds as defined in the documentation. */ do_node( failure ) :- !, fail. do_node( success ) :- !. do_node( A ) :- '$node'( A, Next ), !, do_node( Next ). /* Asserting and retracting nodes. ------------------------------- This section includes the transformation to internal form by 'assert_expanded_atn'. */ retractall_expanded_atn( Node ) :- retractall( '$node'(Node,_) ). assert_expanded_atn( atn(Node,Command,Arcs) ) :- atn_to_clause( Node, Command, Arcs, Clause ), assert( Clause ). atn_to_clause( Node, Command, Arcs, Clause ) :- Clause = (Head :- Tail), Head = '$node'( Node, NextNode ), Tail = (Command , NextNodeGoal), arcs_to_if( Arcs, NextNode, NextNodeGoal ). arcs_to_if( [], succeed, true ) :- !. arcs_to_if( [true,Next|Rest], NextNode, Command ) :- !, Command = ( NextNode = Next ). arcs_to_if( [Cond,Next|Rest], NextNode, Command ) :- Command = ( Cond -> (NextNode = Next) ; RestOfIf ), arcs_to_if( Rest, NextNode, RestOfIf ).