%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                             % 
%  A test file for testing other implementations of the SFST  %
%  programming language. More information on SFST at          %
%  <http://www.ims.uni-stuttgart.de/projekte/gramotron/\      %
%  SOFTWARE/SFST.html>.                                       %
%                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



%%%%%%%%%%  BASIC REGULAR EXPRESSIONS  %%%%%%%%%%


% [^ab]   % if alphabet is not defined, yields an error
% .       %              -- "" --
% !(ab)   %              -- "" --


ALPHABET = [a-e] <> a:b  % epsilon is not included in the alphabet

% $B4$ = f       % f (though 'f' is not in the alphabet)
% f:.          % error 


%%%  any character '.'  %%%


$EMPTY$ = a - a

a:.   ==  ( a | a:b )
.:b   ==  ( b | a:b )
.:<>  ==  $EMPTY$
.     ==  ( [a-e] | a:b )


[ab]:[c]      ==  ( a:c | b:c ) 
[ab]:[a-c]    ==  ( a | b | b:c )
[abc]:[d<>]   ==  ( a:d | b:<> | c:<> )
[abc]         ==  ( a | b | c )
%[^ab]         ==  ( c | d | e | <> )  % (a:b not included) 

% [^a-e<>a:b]   % yields not an empty machine but an error message
                % (in earlier version of SFST this yielded NULL,
		% which is interpreted by function 'new_transducer' as
		% wildcard character, a bug that is fixed now)

{abc}:{de}  ==  ( a:d b:e c:<> )
{de}:{abc}    ==  ( d:a e:b <>:c )



%%% quoted characters and numbers and multi-character symbols %%%

$Q1$ = \32                    % ' ' (the blank character)
$Q2$ = \!                     % '!' (the exclamation mark)
$Q3$ = \\			 % '\' (backslash)
$Q4$ = <Symbol1>:<symbol_2>


% check that the equivalence test works
(a) == (a <>)


%%%%%%%%%%  VARIABLES AND AGREEMENT VARIABLES  %%%%%%%%%%


$Nsg$ = house | foot | mouse
$Npl$ = house<>:s | f o:e o:e t | {mouse}:{mice}
$GENERATE$ = $Nsg$ <N>:<> <sg>:<> | $Npl$ <N>:<> <pl>:<>

^( house<N><sg> || $GENERATE$ )  ==  house
^( house<N><pl> || $GENERATE$ )  ==  houses
^( foot<N><sg>  || $GENERATE$ )  ==  foot
^( foot<N><pl>  || $GENERATE$ )  ==  feet
^( mouse<N><sg> || $GENERATE$ )  ==  mouse
^( mouse<N><pl> || $GENERATE$ )  ==  mice


#LC# = a-c
#UC# = A-C

( [#LC#]:[#UC#]* )  ==  ( ( a:A | b:B | c:C )* )


%%% agreement variables %%%

% $=c$ = a | b* | c   % yields an error, cyclic transducer has infinite paths
$=c$ = [ABC]
$=e$ = e?

$AV1$ = $=c$ $=e$ X $=e$ $=c$  
$AV1$  ==  ( AeXeA | BeXeB | CeXeC | AXA | BXB | CXC )

#=c# = abc
$AV2$ = [#=c#] X <>:[#=c#]     
$AV2$  ==  ( aX<>:a | bX<>:b | cX<>:c )  % HWFST
% $AV2$ >>>



%%%%%%%%%%  OPERATORS  %%%%%%%%%%


$OP1$ = a bc                       % concatenation

$OP2$ = a | b | cd                 % disjunction, union 

$OP3$ = a:b || b:c                 % (composition)
$OP3$ == ( a:c )


( a:[b<>] )  ==  ( a:b | a:<> )
( <>:[cd] )  ==  ( <>:c | <>:d )


$OP4$ = a:[b<>] || <>:[cd]         % check if this is correct
$OP4$ == (  ( (<>:c|<>:d) a:<> ) | ( a:<> (<>:c|<>:d) )  ) % HFST, HWFST

$OP5$ = [ab] & [bc]		   % b (intersection, conjunction) 
$OP5$ == b 

$OP6$ = [ab<>]:[de] & [<>]:[ea]    %  
$OP6$ == <>:e    

$N$ = !(a:<> | bc)	           % (negation, complement)

$OP7$ = (a:<> & $N$) (bc & $N$)    % empty transducer  %% memory leak in hwfst
$OP7$ == $EMPTY$

$OP8$ = (a:b & $N$) (bc:d & $N$)   % a:b 
$OP8$ = a:b

$OP9$ = . - [a-c]                  % (subtraction, difference)
$OP9$ == ( d | e | a:b )  % HWFST

$NEG$ = !a
$SUB$ = (.*) - a
$OP10$ = $NEG$ - $SUB$              % empty transducer, negation defined through 
			            % subtraction/difference: !r = (.*) - r
$OP10$ == $EMPTY$  % HFST


$OP11$ = ab?c                       % optionality
$OP11$ == (abc | ac) 

$OP11b$ = e?
$OP11b$ == (e | <>)  % HFST, HWFST

$OP12$ = ab*c                       % Kleene's star
$OP12test$ = ( ac | abc | abbbbbbc )
( $OP12$ & $OP12test$ )  ==  $OP12test$

$OP13$ = ab+c                       % Kleene's plus (r+ = rr*)
( $OP13$ & $OP12test$ )  == ( abc | abbbbbbc )

$OP14$ = ^$GENERATE$                       % mice, ... (range)             % different
$OP14$ == ( house|houses|foot|feet|mouse|mice )  % HFST, HWFST

$OP15$ = _$GENERATE$                       % mouse<N><pl>, ... (domain)    % different
$OP15$ == ( house<N><sg>|house<N><pl>|foot<N><sg>|foot<N><pl>|mouse<N><sg>|mouse<N><pl> ) % HFST, HWFST

$OP16$ = ^_$GENERATE$                      % (inversion)
^( house  || $OP16$ )  ==  house<N><sg> % HWFST
^( houses || $OP16$ )  ==  house<N><pl>  % HWFST
^( foot   || $OP16$ )  ==  foot<N><sg>  
^( feet   || $OP16$ )  ==  foot<N><pl> 
^( mouse  || $OP16$ )  ==  mouse<N><sg> 
^( mice   || $OP16$ )  ==  mouse<N><pl>  % until this HWFST


$OP17$ = (a:b c:d e:<>) << x        % (insertion)
$OP17$ == ( x* a:b x* c:d x* e:<> x* )





%%%%%%%%%%  TWO-LEVEL RULES  %%%%%%%%%%

ALPHABET = [a-e] <> a:b

%% note that the mapping defined in the rule must be included in the alphabet

% a _must_ be mapped to b between c and c, a _can_ be mapped to b elsewhere

$R1$ = c a <= b c

ca:bca & $R1$   ==  c a:b c a
cac & $R1$      ==  (a-a)   % empty
aca:b & $R1$    ==  a c a:b


% a _can_ be mapped to b between c and c, a _cannot_ be mapped to b elsewhere

$R2$ = c a => b c

ca:bcaca & $R2$   ==  c a:b c a c a
cac & $R2$        ==  c a c
ca:b & $R2$       ==  (a-a)     % empty


% a _must_ be mapped to b between c and c, a _cannot_ be mapped to b elsewhere

$R3$ = c a => b c

ca:bca & $R3$     ==  c a:b c a
cac & $R3$        ==  a-a       % empty
ca:b & $R3$       ==  a-a       % empty



%%%%%%%%%%  REPLACE OPERATORS  %%%%%%%%%%


% note: optional mapping either happens everywhere where it is possible 
% or nowhere (unless it is included in the alphabet) 

ALPHABET = [abc]


$UP$ = a:b ^-> ()      % upward replacement
acaca || $UP$    ==  a:b c a:b c a:b

$UP$ = a:b ^-> ? ()    % optional upward replacement
acaca || $UP$    ==  acaca | a:b c a:b c a:b

$DOWN$ = a:b _-> ()    % downward replacement
$DOWN$ || bcbcb  ==  a:b c a:b c a:b

$DOWN$ = a:b _-> ? ()  % optional downward replacement
$DOWN$ || bcbcb  ==  a:b c a:b c a:b | bcbcb


$UP$ = a:b ^-> (c__c)      % upward replacement
acacaca || $UP$  ==  ac a:b c a:b ca

$UP$ = a:b ^-> ? (c__c)    % optional upward replacement
acacaca || $UP$  ==  acacaca | ac a:b c a:b ca

$DOWN$ = a:b _-> (c__c)    % downward replacement
$DOWN$ || bcbcbcb   ==  b c a:b c a:b c b

$DOWN$ = a:b _-> ? (c__c)  % optional downward replacement
$DOWN$ || bcbcbcb   ==  bc a:b c a:b cb | bcbcbcb


$UP$ = b:a ^-> (a__)         % upward replacement
abbbbb || $UP$      ==  {abbbbb}:{aabbbb}

$LEFT$ = b:a /-> (a__)       % leftward replacement
abbbbb || $LEFT$    ==  {abbbbb}:{aaaaaa}

$UP$ = b:a ^-> (__a)         % upward replacement
bbbbba || $UP$      ==  {bbbbba}:{bbbbaa}

$RIGHT$ = b:a \-> (__a)      % rightward replacement
bbbbba || $RIGHT$   ==  {bbbbba}:{aaaaaa}

$UP$ = (c:a a* c:a) ^-> (c__c)   % upward replacement
cccaccc || $UP$     ==  {cccaccc}:{ccaaacc}

$DOWN$ = (c:a a* c:a) _-> (c__c) % downward replacement
%cccaccc || $DOWN$                % {cccaccc}:




%%%%%%%%%%  RESTRICTION AND COERCION OPERATORS  %%%%%%%%%%

ALPHABET = [abc] a:b

$RESTR$ =  a:b => (c__c)
acacaca || $RESTR$  ==  {acac}:{acac} | {acac}:{acbc}

$RESTR$ =  a:b <= (c__c)
acacaca || $RESTR$  ==  {acac}:{acbc} | {acac}:{bcbc}

$RESTR$ =  a:b <=> (c__c)
acac || $RESTR$  ==   {acac}:{acac} | {acac}:{acbc}


$RESTR$ =  a:b ^=> (a__)
aaaa || $RESTR$  ==  aaaa | aaaa:b | aaa:ba | aa:baa | aa:baa:b

$RESTR$ =  a:b ^<= (a__)
% aaaa || $RESTR$ %

$RESTR$ =  a:b ^<=> (c__c)
% acac || $RESTR$ % acac ->

a

%%%%%%%%%%  CREATING, READING AND WRITING TRANSDUCERS  %%%%%%%%%%


% file "adj" includes 'big', 'small', 'dark' and 'white'

% $ADJ$ = "adj"
% $ADJ$	                              % big | small | dark | white
% <A> >> "tag.a"
% $ADJ$ "<tag.a>" >> "adjectives.a"
% "<adjectives.a>"                    % big<A> | small<A> | dark<A> | white<A>













% $WORD$ || $R1$
% $WORD$ || $R1$
% !(a:b .* | .* a:b !(r.*)) & !(.* (a:. & !a:b) r.*)
% .* (a:. & !a:b) c % .*
% $WORD$ || $R1$
% a:bbc | $ADJ$
% a b | c
% ab << c
% !( bc | c )
% $A1$ = a | b | c
% $A2$ = bb | bc | ca
% $A1$
% $A1$ - $A2$
% .
% <>:a | <>:b



% $R2$ = c a <= b c
% ca:bca:bca:b & $R2$  % included in $R1$

% $R3$ = a => b c
% aca:bb & $R3$     % empty, a:b allowed only before c
% aca:bc & $R3$     % included in $R3$, a:b not obligatory before c

% $R5$ = a <=> b c
% a:bca:b & $R5$    % empty

% $R6$ = c a <=> b c
% ca:bca:b & $R6$   % empty
