-- Answer to Q2.

-- Recursive version - no checking for duplicates

#Go

      PRINT #FindVars( <. C1 : <. I : X, E : <. N : 0 .> .>, C2 : <. I : Y, E : <. N : 1 .> .> .> )

##

#FindVars

      <* $Sel : $L !!:= #FindVars *> /  RETURN $L / ;;

      $Leaf / IF #IDENT($Leaf) -> RETURN (. $Leaf .) FI /

##

 

-- Answers to Q3.

-- Recursive version with use of 'global' variable, and checking for duplicates

#Go

      #FindVars( <. C1 : <. I : Y, E : <. N : 0 .> .>,

                   C2 : <. C1 : <. I : X, E : <. N : 1 .> .>,

                         C2 : <. I : Y, E : <. N : 2 .> .> .> .>);

      PRINT $A

##

#FindVars

      <* $Sel : #FindVars *>  ;;

      $Leaf / $T := LAST #Go $A;

            IF #IDENT($Leaf) ->

                IF NOT #Mem($Leaf $T) -> LAST #Go $A !.:= $Leaf FI FI /

##

#Mem

      $L (. (* $Item / IF $L = $Item -> RETURN T FI / *) .)

##

 

-- Recursive version with accumulator and checking for duplicates

#Go

      PRINT #FindVars($L <. C1 : <. I : Y, E : <. N : 0 .> .>, C2 : <. I : Y, E : <. N : 2 .> .> .> )

##

#FindVars

      $L <* $Sel : $ST

                  / $L := #FindVars($L $ST) / *>

            / RETURN $L / ;;

      $L $Leaf

            / IF #IDENT($Leaf) ->

                  IF NOT #Mem($Leaf $L) -> RETURN $L !. $Leaf

                  FI

              FI;

              RETURN $L/

##

#Mem

      $L (. (* $Item / IF $L = $Item -> RETURN T FI / *) .)

##