#!/usr/bin/env perl
use warnings;
use utf8;
BEGIN { $| = 1; }

#########################################################################
#### Generator for dependency trees
#### Author: © Eckhard Bick 2005,2017; contact: eckhard.bick@mail.dk ####
#########################################################################
#
# use: cat file.syn | cg2dep pt > file.dep
#
# adds dependency structures to input annotated with morphosyntactic CG tags
# reads and compiles rules file with dependency attachment rules (pordep)
# exploits special tags for close/long attachment and coordination
#   added by portcg.attach
#
# * uses Melczuk convention for coordination, attaching second and later conjuncts to, and the coordinator, to the first conjunct as head
# * treats the first verb as (syntactic) head of a verb chain, i.e. auxiliaries as heads of main verbs.
# * treats prepositions as (syntactic) heads of pp's
# * treats subordinators and articles as dependents, not heads
# * treats copula verbs as heads of subjects and subject complements
#
# To change syntactic dependencies into semantic dependencies, use visldep2ud.pl converter (Universal Dependencies, under development)
#
# Input format is expected as "niceline", not cohort format
# word     [base] <...> ... POS MORF ... @FUNC
#
# The output contains additional #n->m attaching dependents (n) to heads (m)
# Also adds </s> delimiter tags.
# Respects <....> meta lines in input
#
# Pipe flow: "| cg2dep pt" is run after portcg.attach, and needs <...> tag standardization carried out by remove_secondary.portdep and remove_secondary.europarl-pt
#
#########################################################################

$lang =$ARGV[0];
if ($lang && $lang =~ s/1//) {$test =1;} # append '1' to input for test run
else {$test =0;}

if ($lang) {$lang =~ s/^.*([a-z][a-z])$/$1/;}
else {$lang ="da";}
my ($binDir, $sep) = $0 =~ /^(.*)(\\|\/).*/;
$ENV{DANGRAM_BIN} = "$binDir";
$ENV{DANGRAM_ETC} = $etcDir = "$binDir/../etc";

####### Danish ### The reason for attaching ADVL> to VFIN (and not <mv>) - the latter yields a strange crossing branch in cases where Paux har en Oaux:par-daughter: ... 'og hver gang ADVL> jeg skulle rejse hjem igen, har jeg haft nedtur og følt at', plus ADVL> does really belong to both AUX<'er -- on the other hand that is true of >>P also: .. det har jeg tænkt over og glædet mig til

$t =0;
$rep =0;
$num =0;
#$test =1;
#$lang ="da";

if ($lang eq "da") {open(FH, "<$etcDir/dandep");}
elsif ($lang eq "de") {open(FH, "<$etcDir/gerdep");}
elsif ($lang eq "en") {open(FH, "<$etcDir/engdep");}
elsif ($lang eq "EN") {open(FH, "<$etcDir/engdep");}
elsif ($lang eq "eo") {open(FH, "<$etcDir/espdep");}
elsif ($lang eq "es") {open(FH, "<$etcDir/hisdep");}
elsif ($lang eq "it") {open(FH, "<$etcDir/hisdep");}
elsif ($lang eq "pt") {open(FH, "<$etcDir/pordep");}
elsif ($lang eq "sv") {open(FH, "<$etcDir/svedep");}
else {open(FH, "<$etcDir/dandep");}

#print "------lang=$lang\n";
$rep =0;

while (<FH>) {
    $rulenr++;
    if (/^(¤[^ =]+) *= *([^\#\n]+)/) {
	$replace[$rep] =$1 . "=" . $2;
	$replace[$rep] =~ s/ +$//;
	$rep++;
#	print "___replace $1 $2\n";
    }
    if (/->.*IF/ && ! /^\#/) {
	$rep--;
	s/#.*//;
	s/\"(.*?)\"/\\[$1\\]/g;
	s/ -> /\;/;
	s/ IF /\;/;
	chop;

### unfold variables
	$line =$_;
	foreach (@replace) {
	    ($variable,$ny) = split /=/;
	    $line =~ s/$variable/$ny/g;
#	    print "$line\n";
	}

	($target,$head,$conditions) = split /\;/, $line;
	$target =~ s/ +/.*/g;
	$conditions =~ s/SEMICOLON/\;/g;
	if (! $ct{$target}) {
	    $targets[$t] =$target;
	    $t++;
	}
	$ct{$target}++;

#	$head =~ s/[\(\)]//g;
	$head =~ s/,/\|/g;
	$heads{$target}[$ct{$target}] =$head;
	$rules{$target}[$ct{$target}] =$conditions;
	$ruleid{$target}[$ct{$target}] =$rulenr;
#	print "***" . $target . " " . $rules{$target}[$ct{$target}] . "---\n";
    }
}

while (<STDIN>) {
    s/[\r\n]+/\n/; # DOS->linux normalisation

     if (/^<s[ _].*(id|ID)=/) {$sentid =$_; $sentchild=1;}
    if ($sentend && /^<\// || $sentend && /^[ \t]*$/ || /^<\/(s|it|ß)/ || /\$¶/) {
	if ($num) {&runall;}
	if (/^\$¶/) {
	    $num =-1;
	    if ($sentid) {
		$sentchild++;
		$sentidnew =$sentid;
		$sentidnew =~ s/((id|ID)=\"?[a-zA-Z0-9]+)\"/$1-$sentchild\"/;
		if ($meta) {print $meta; $meta ="";}
	    }
	    else {
		print "\$¶\n";
	    }
	}
    }

### comments
    if (/^[<\#]/) {
	if (! $num) {
	  print; # meta lines *before* sentence (as well as </s> which occurs *after* $num has been zeroes due to &print)
	}
	else {
	  $meta .= $_; # meta lines *after* sentence
	}
	if (/<\/[sß]>/) {print "\n";}
	goto slut;
    }
    elsif (! /^ *$/) {$num++;}
    chop;

### text lines

    if (/\@>[ANPS]/) {s/(\[(ikke|kun|selv|endda|allerede|end=ikke|i=det=mindste|i=hvert=fald|måske|også|selv)\])/$1 <foc>/;}
    s/\@(FMV|FAUX)/\@FS-STA/g;
    s/\@(IMV|IAUX)/\@ICL-UTT/g;
    if (! /\@(FS|ICL|AS)?-?(N<|APP)/) {s/ <np-(close|long)>//g;}

    if ($lang eq "pt") { # this is also done in portcg2vislcg, just to be on the safe side
      s/(\@<*)ADVO/$1OA/;
      s/(\@<*)ADVS/$1SA/;
      s/(\@<?)ADV([> \n])/$1SA$2/; # including the underspecified @<ADV
    }

#    s/[\t ]+\[.*?\].* PU .*//; # PAR-L etc.

   if (/<quote>/ && ! /(ACC>|(FS|ICL)-|\@<)/) {s/\@[^ \n]+/\@ACC>/;} # interjections etc. made functionally dependent on quoting verbs, 'Nej, jeg vil hellere ud i haven, tænkte hun' --- cave clausal subjects (...., anføres det) or left-pointing <quote>-functions

    s/\t/ /g;
    s/[ \t]+#.*//; # comments in revised corpus
    s/(FS|ICL|AS)-/$1-\@/g; # so @<ACC can be used for @FS-@<ACC, too
    $lines[$num] = " " . $_ . " ";
    $lines[$num] =~ s/  +$/ /;
    $dep[$num] =0;
		if ($lines[$num] =~ / \@([^ ]+) /) {
		    $func[$num] =$1;
		}
    else {$func[$num] = "PU";}
#		    print "func $num $func[$num]\n";

### sentence delimiters
    if (/^ ?\$?[\.:\;\?\!¶]/ || EOF) {
	$sentend =1;
    }
  slut:
}
if ($sentend && $num) {
    &runall;
}
if ($betaopen) {print "</ß>\n";}

sub runall {
    $circ =5;
  circrepeat:
    &target_driven_dependency;
#	&token_driven_dependency;
    if ($rerun) {$rerun =2; &token_driven_dependency;}
    $circularity =""; $ambi ="";

    if ($circ <4) {
	&circularcheck;
	$circ++;
    }
    if (($circularity || $ambi) && $circ <4) {
	&allzero;
	for ($i =1; $i <=$num; $i++) { # remove all changes
	    $dep[$i] =0;
	    $lines[$i] =~ s/<cjt[^>]*> //g;
	}
	goto circrepeat;
    }
    $unattached=0;
    @missing=();
    for ($i =1; $i <=$num; $i++) {
      if ($dep[$i] ==0 && $lines[$i] =~ /\@(<|[^ ]+[\<\>])/) {
	$unattached++;
	$missing[$i] =1;
      }
    }
#    print "--unattached=$unattached\n";
    if ($unattached) {
#      print "*****unattached=$unattached\n";
      &target_driven_dependency; # handles the last zeros by not letting a rule be put off by uniqueness, head conditions etc.
    }
    &addcjthead;
    &nplongadapt;
#    for ($printi=1; $printi <= $num; $printi++) {print "----------$printi->$dep[$printi]\n"}
    &print;
    if ($meta) {print "$meta"; $meta ="";}
    &allzero;
    @tabuheads =();
    $num =0; $sentend =0;
    @func =();
#	@lines ="";
}

sub allzero {
    $rerun =0; $topeye =0;
    @daughters ="";
    @offspring ="";
    @depchain ="";
    @dep =();
    @headblockright =();
#    @tabuheads =();
    @fixdep =();
    $unattached=0;
    @missing=();
}

sub target_driven_dependency {
    foreach (@targets) {
#      print "******$_\n";
	$target =$_;
#	for ($i =$num; $i >0; $i--) {
	for ($i =1; $i <=$num; $i++) {
	    if (! $dep[$i] || 1==1 && ! $unattached || $missing[$i]) {

		$line =$lines[$i];
#		if ($unattached) {print "*---target=$_ line=$line***\n"; if ($missing[$i]) {print " missing $i=$missing[$i]\n";}}
		if ($line =~ / (\@[&\#]?(FS|ICL|AS)-)?$target / || $line =~ /^$target *$/) {
		  if ($lines[$i] =~ m/ \@([^ \n]+)/) {
		    $func[$i] =$1;
		  }
		  else {$func[$i] = "PU";}
#		    $func[$i] =~ s/\@/\\\@/;
#		    print "######target=$_ " . " i=$i func=$func[$i] line=$line conditions=$rules{$target}[$ct{$target}] [$ct{$target}] \n";

		    for ($j =1; $j <= $ct{$target}; $j++) {
			$conditions =$rules{$target}[$j];
			if ($dep[$i] && ! ($conditions =~ /\(D\)/)) {
#			    print "$i->$dep[$i] - ";
			    next;
#			    goto nomorerules;
			}
#			print "###$i target=$target head=$head conditions=$conditions\n";
			if ($conditions =~ /HEADCHILD=(\(.*?\))/) {
			    $headchild =$1;
			    $headchild =~ s/,/\|/g;
#			    print "***headchild-condition=$headchild\n";
			}
			else {$headchild ="";}
			if ($conditions =~ /NOTHEAD=(\(.*?\))/) {
			    $nothead =$1;
			    $nothead =~ s/,/\|/g;
#			    print "***nothead-condition=$nothead\n";
			}
			else {$nothead ="";}
			if ($conditions =~ /NOTTARGET=(\(.*?\))/) {
			    $nottarget =$1;
			    $nottarget =~ s/,/\|/g;
#			    $nottarget =~ s/-\@/-/g;
#			    print "***testing $line for nottarget $nottarget\n";
			    if ($line =~ / $nottarget /) {
#				print "******target=$target nottarget-condition=$nottarget $line rule $ruleid{$target}[$j]\***\n";
				$nottarget ="";
				next;
#				goto nomorerules2;
			    }
			}
			else {$nottarget ="";}
			if ($conditions =~ /TRANS:(\(.*?\))/) {
			    $trans =$1;
			    $trans =~ s/,/\|/g;
#			    print "***trans-condition=$trans\n";
			}
			else {$trans ="";}
			if ($conditions =~ /BARRIER:(\(.*?\))/) {
			    $barrier =$1;
			    $barrier =~ s/,/\|/g;
#			    $barrier =~ s/\}/\)/; # maybe to be activated: one way of being able to include brackets
#			    print "***barrier-condition=$barrier\n";
			}
			else {$barrier ="";}
#		    print "her: $conditions\n";
			$head =$heads{$target}[$j];
			if ($conditions =~ /\(D\)/ && $daughters[$i] && $daughters[$i] =~ / $head[0-9]/) {
#			print "### NO: $i target=$target head=$head conditions=$conditions\n";
			    next;
#			    goto nomorerules;
			}
#			print "### $i target=$target head=$head conditions=$conditions\n";
#			if ($daughters[$i]) {print "---daughters: $daughters[$i]\n";}

			if ($conditions =~ /^\(L/) {
			    &findheadleft;
			}
			elsif ($conditions =~ /^\(R/) {
			    &findheadright;
			}
			else {
			    &findheadleft;
			    &findheadright;
			}

		      nomorerules:
			if ($lines[$i] =~ m/ \@([^ \n]+)/) {
			  $func[$i] =$1;
			}
			else {$func[$i] ="PU";}

			if ($conditions =~ /\(F\)/) {
			    $fixdep[$i] =1;
			}
#			for ($printi=1; $printi <= $num; $printi++) {print "----------$printi->$dep[$printi]\n"}
#			print "------i=$i head=$dep[$i] target=$target offspring(head)=$offspring[$dep[$i]]\n";

### til ... fra
			if ($lang eq "da" && $lines[$i] =~ /\[til\]/ && $lines[$dep[$i]] && $lines[$dep[$i]] =~ /\[fra\]/ || $lang eq "pt" && $lines[$i] =~ /\[a\]/ && $lines[$dep[$i]] && $lines[$dep[$i]] =~ /\[de\]/ || $lang eq "en" && $lines[$i] =~ /\[to\]/ && $lines[$dep[$i]] && $lines[$dep[$i]] =~ /\[from\]/ || $lang eq "eo" && $lines[$i] =~ /\[al\]/ && $lines[$dep[$i]] && $lines[$dep[$i]] =~ /\[de\]/) {
#			    print "------$dep[$i] $dep[$dep[$i]]\n";
			    $dep[$i] =$dep[$dep[$i]] ; # raise to common head
			}
			if ($lines[$i] =~ / IN .*\@ADVL[^>]/ && $dep[$i] && $offspring[$dep[$i]]  =~ /co-/) {
#			    print "*------$i $dep[$i] $offspring[$dep[$i]]\n";
#			    $lines[$i] =~ s/\]/\] <cjt>/; # men nej, den gik altså ikke [da59]
			    $cjti =$i; &addcjt;
			}

### ellipsis

			if ($dep[$i] && $conditions && $conditions =~ /\(ADD:([^\)]+)\)/) {
			    $add =$1;
			    if (! ($lines[$i] =~ / $add /)) {
				$lines[$i] =~ s/\]/\] $add/; # fordi næsen var for lille og munden lidt for stor
			    }
			}

### headblockright
			$baseA= ""; $baseB ="";
			if ($lines[$dep[$i]]) {
			  $lines[$dep[$i]] =~ /\[(.*?)\]/; $baseA =$1;
			  $lines[$i] =~ /\[(.*?)\]/; $baseB =$1;
			}
			if ($baseA && $baseB) {$basechain =$baseA . $baseB;}
			else {$basechain ="xxxxxx";}
			if ($dep[$i] && $dep[$i] < $i && $lines[$dep[$i]] =~ / (PRP|ADV|ADJ|DET|NUM) / && ! ($lines[$i] =~ /(cjt|\[(med|til)\]|\@(ADVL|NPHR|CO|S<) )/) && ! $basechain =~ /^deal$/) { # disse ordklasser tager aldrig mere end een højre dependent, ikke: lyslevende fra ... til, enig med X i Y
			    $headblockright[$dep[$i]] =1;
#			    print "----headblockright: $dep[$i]\n";
			}

### co-ordination

			if ($func[$i] =~ /FS-\@(<SUBJ|<SC)/ && $func[$dep[$i]] && $func[$dep[$i]] =~ /$func[$i]/) {
#			    print "------$func[$i] $func[$dep[$i]]\n";
#			    $lines[$i] =~ s/\]/\] <cjt>/ ; # conjunct
			    $cjti =$i; &addcjt;
			}
			if ($func[$i] =~ /ICL-\@(<SUBJ|<SC|UTT)/ && $func[$dep[$i]] && $func[$dep[$i]] =~ /$func[$i]/) {
#			    print "------$func[$i] $func[$dep[$i]]\n";
#			    $lines[$i] =~ s/\]/\] <cjt>/ ; # conjunct
			    $cjti =$i; &addcjt;
			}


#			print "______$dep[$i] $daughters[$dep[$i]]\n";
			if ($dep[$i] && $daughters[$i] && $daughters[$i] =~ /<co-([a-z]+)>/ && ! ($lines[$i] =~ /<cjt>/)) { # if not already recognized as conjunct
			    $cotype =$1; $hoved =$dep[$i];
			    if (! $cotype) {$cotype ="co";}

			    $cotype =~ s/prparg/P</;
			    $cotype =~ s/postnom/N</;
			    $cotype =~ s/prenom/>N/;
			    $cotype =~ s/postad/A</;
			    $cotype =~ s/pread/>A/;
			    $cotype =~ s/subj/SUBJ/;
			    $cotype =~ s/acc/ACC/;
			    $cotype =~ s/dat/DAT/;
			    $cotype =~ s/piv/PIV/;
			    $cotype =~ s/advl/ADVL/;
			    $cotype =~ s/sc/SC/;
			    $cotype =~ s/oc/OC/;
			    $cotype =~ s/sa/SA/;
			    $cotype =~ s/oa/OA/;

			    $headdaughters =$daughters[$hoved];
			    $foundfirstcjt =0;
#			    print "$hoved headdaughters =$headdaughters\n";
			    while (! $foundfirstcjt && $headdaughters =~ s/ [^ ]*?$cotype[^ 0-9]*([0-9]+)//) {
				$firstcjt=$1;
				if (! ($cotype =~ />N/ && $lines[$firstcjt] =~ / (ART|DET|NUM) / && ! ($lines[$firstcjt+1] =~ /(KC|\$,)/))) {$foundfirstcjt =1;}
#				print "--$hoved $foundfirstcjt $lines[$firstcjt]\n";
			    }
#			    print "$hoved headdaughters =$headdaughters\n";
#			    $firstcjt =$1;
#			    $lines[$firstcjt] =~ s/\]/\] <cjt>/g; # gives errors??? - og vil nu også kræve tilpasning i visldep2malt.pl
			    while ($headdaughters =~ s/ [^ ]*?$cotype[^ 0-9]*([0-9]+)//) {
				$latercjt =$1;
				$dep[$latercjt] =$firstcjt;
				$daughters[$hoved] =~ s/ [^ ]*?$cotype$latercjt([0-9]+)//;
#				$lines[$latercjt] =~ s/\]/\] <cjt>/g;
				$cjti =$latercjt; &addcjt;
#				print "____latercjt=$latercjt line=$lines[$latercjt]\n";
			    }

#			    print "_____i=$i hoved=$dep[$i] cotype =$cotype headdaughters=$headdaughters firstcjt=$firstcjt\n";
			    $firstcjt =0;
			}
		      nomorerules2:
		    }
		}
	    }
	}
    }
}


sub findheadleft {
#    my $eye;
    $iek =$i;
#	print "###----------target=$target i=$i eye=$eye head=$head rule $ruleid{$target}[$j]\n";
#    if ($target =~/FS/ && $daughters[$i]) {print "***i=$i daughters=$daughters[$i]\n";}
    if ($target =~ /\@FS-\@</ && $daughters[$i] && $daughters[$i] =~ /\@[FSR]?\-?SUBJ>([0-9]+)/) {
	$iek =$1; # jumping to the start of subclause -- IKKE $1-1, fordi eye-sløjfen starter endnu en -1 længere til venstre, så at fx <clb> trans-conditions ikke fanges (systemet kan ikke tilpasses en sikker <clb> - UDEN brug af clb-trans - fordi dansk ikke har sikker <clb>??)
#	print "***new iek=$iek\n";
    }
    $eyesused = "xxx";
    for ($eye =$iek-1; $eye >0 && $eyesused !~ / $eye / ; $eye--) {
      $eyesused .= " $eye ";
#      print "--eye=$eye iek=$iek";
      $coretarget ="";
      if ($lines[$eye] =~ /\$\).*PAR-R/) { # skal have PAR-R tag, otherwise oddities like )( give problems
#	if ($lines[$eye] =~ /\$\) /) { # skal have PAR-R tag, otherwise oddities like )( give problems
	while ($eye >0 && ! ($lines[$eye] =~ /\$\(/)) {$eye--;}
      }
      elsif ($lines[$eye] =~ /\$\".*PAR-R/) {
	while ($eye >0 && ! ($lines[$eye] =~ /PAR-L/)) {$eye--;}
      }
      elsif ($lines[$eye] =~ /\$-R.*PAR-R/) {
	while ($eye >0 && ! ($lines[$eye] =~ /\$-L/)) {$eye--;}
      }
      elsif ($lines[$eye] =~ /<pu-right>/) {
	while ($eye >0 && ! ($lines[$eye] =~ /<pu-left>/)) {$eye--;}
      }
      elsif ($lines[$eye] =~ /<postcond>/ && ! ($head =~ /<postcond>/)) {
	while ($eye >0 && ! ($lines[$eye] =~ / <clb> /)) {$eye--;}
      }
      elsif ($lines[$eye] =~ /<cle>/) {
	while ($eye >0 && ! ($lines[$eye] =~ / <clb> /)) {
	  #	      print "----i now $i, eye now $eye\n";
	      $eye--;
	      if ($eye ==0) {return;}
	    }
      }
	elsif ($lines[$eye] =~ /\@CO/ && $daughters[$eye] && $daughters[$eye] =~ /\@FOC>([0-9]+)/) { # dels ... dels, både ... og
#	    print "------$eye changed to $1\n";
	    $eye =$1;
	}
	if ($eye > 0 && $lines[$eye] =~ / ADJ / && $daughters[$eye] && $daughters[$eye] =~ /\@ADVL>A([0-9]+)/ && ! ($lines[$eye] =~ / $head /)) {
	  $eye =$1; # jumping across @ADVL>A - ADJ PART bracket in German
	    #	print "***new eye=$eye for i=$i\n";
	}
	if ($lines[$i] =~ /\@FS/ && $daughters[$i] && $daughters[$i] =~ / (\@[FSR]?-?<?SUBJ?>?|<clb>|<rel>|<interr>)([0-9]+)/ && $2 < $eye && $2 >0 && ! ($conditions =~ /\(D\)/)) { # D=inverse dependency might be looking for subject
#	    print "---her: i=$i eye=$eye head=$head sub/subject-jump to neweye=$2 -1 conditions=$conditions\n";
	    $eye =$2-1;
	    if ($eye ==0) {return;}
	    if ($trans =~ /\@[FSR]?-?<?SUBJ?>?/) {$trans ="";}
	}

#	print "----------target=$target i=$i eye=$eye head=$head rule $ruleid{$target}[$j]\n";
	if ($eye > 0 && ($lines[$eye] =~ / $head / && (! $tabuheads[$i] || ! ($tabuheads[$i] =~ / $eye /)) && (! $headchild || $daughters[$eye] && $daughters[$eye] =~ / $headchild/) && (! $nothead || ! ($lines[$eye] =~ / $nothead /)) && ! $trans || $lines[$eye] =~ /\Q$func[$i]\E/ && $daughters[$eye] && $daughters[$eye] =~ /co-([a-z]+)/ && ($comatch =$1) && $daughters[$i] && $daughters[$i] =~ /co-$comatch/)

	    && (! ($lines[$i] =~ /<cjt>/) || $target =~ /(\@(FS|ICL|AS)-)?\@<?(SUBJ|R-<?SUBJ|ACC|DAT|SC|OC|SA|OA|P<|AUX<)>?/ && ($coretarget=$3) && $daughters[$eye] && $daughters[$eye] =~ /\@<?$coretarget>?([0-9]+)/ || ! $coretarget || $lines[$eye] =~ /\@<?$coretarget>? / || $lines[$eye] =~ /\@(STA|QUE|UTT)/) # coretarget must either be daughter of eye (indirect <cjt> attachment through normal rules) or part of eye itself (direct <cjt> attachment)

 && (! $circularhead || $circularhead != $eye)

) { # must also handle 3->2->1 coordination
#	    if ($depchain[$eye]) {print "depchain=$depchain[$eye]\n";}

	  $origeye =$eye; # remember original eye
#	  print "----daughters($eye)= $daughters[$eye]\n";
	  if ($func[$i] =~ /^([AN]<.*)$/ && ($coretarget=$1) && $daughters[$eye] && $daughters[$eye] =~ /\@\Q$coretarget\E([0-9]+)/) {
	    $fd =$1;
	    $lines[$fd] =~ m/\[(.*?)\]/; $fd_base =$1;
	    if ($lines[$i] =~ /\[\Q$fd_base\E\]/) {
	      $eye =$fd;
	      $lines[$i] =~ s/\] /\] <cjt> /;
	    }
#	    print "--checking for A</N< coordination: fd=$fd fd_base=$fd_base eye=$eye\n";
	  }

	    if ($test) {print "---*1a*--i=$i target=$target eye=$eye func(i)=$func[$i] rule $ruleid{$target}[$j] nottarg=$nottarget circ=$circularhead--\n";} # daughters=$daughters[$eye]
	    if  ($depchain[$eye] && $depchain[$eye] =~ / $i /) { # cave circularity type 1
	      $eye =$origeye;
		if (! $fixdep[$eye] && ! ($conditions =~ /\(D\)/)) {
		    $circularhead =$eye;
		    $topeye =$depchain[$eye];
		    $topeye =~ s/ *$i */ /; # remove self from depchain
		    $topeye =~ s/^.* ([^ ]+) *$/$1/; # find first/upper in chain
		    $topeye =~ s/^ +$//;
		    if (! $topeye) {$topeye = $eye;}
		}
#	print "*** cave circularity $i $target -> $eye ($origeye) topeye=$topeye depchain=$depchain[$eye];\n";
	    }
	    elsif  ($offspring[$i] && $offspring[$i] =~ /[^0-9]$eye /) { # cave circularity type 2 ('når han var ude at $sejle')
	      $eye =$origeye;
		if (! ($conditions =~ /\(D\)/)) { # untested addition a la circularity type 1
		    $circularhead =$eye;
		    $topeye =$depchain[$eye];
		    $topeye =~ s/ *$i */ /; # remove self from depchain
		    $topeye =~ s/^.* ([^ ]+) *$/$1/; # find first/upper in chain
		    $topeye =~ s/^ +$//;
		    if (! $topeye) {$topeye = $eye;}
		}
#		print "*** cave2 circularity $i $target -> $eye topeye=$topeye depchain($eye)=$depchain[$eye]\n";
	    }
	    elsif ($unattached && ! ($conditions =~ /\(D\)/)) {
#	      print "--attaching $i\n";
	      $dep[$i] =$eye;
	      $daughters[$eye] .= " $func[$i]$i";
	    }
	    elsif (($target =~ /(\@(FS|ICL|AS)-)?\@<?(R-<?SUBJ|SUBJ|ACC|DAT|SC|OC|SA|OA|P<|AUX<|KOMP<)>?/ && ($coretarget=$3) && $daughters[$eye] && $daughters[$eye] =~ /\@<?$coretarget>?([0-9]+)/ && ($daughter =$1) || $target =~ /<ADVL/ && $daughters[$i] && $daughters[$i] =~ /<co-advl>/ && $daughters[$eye] && ($daughters[$eye] =~ /\@<ADVL([0-9]+)/ && $1 < $i || $daughters[$eye] =~ / \@<ADVL([0-9]+)/ && $1 < $i) && ($daughter =$1) || $target =~ /<PRED/ && $daughters[$i] && $daughters[$i] =~ /<co-pred>/ && $daughters[$eye] && $daughters[$eye] =~ /\@<PRED([0-9]+)/ && ($daughter =$1)) && ! ($conditions =~ /\(D\)/)) { # not /^ ... otherwise (NOM|ACC).*@<SC won't match
#	    elsif ($target =~ /^((\@(FS|ICL|AS)-)?\@<?(SUBJ|ACC|DAT|SC|OC|SA|OA|P<)>?)/ && ($coretarget=$3) && $daughters[$eye] && $daughters[$eye] =~ /\@<?$coretarget>?([0-9]+)/ && ($daughter =$1)) {
####
### && $func[$daughter] eq $func[$i]
#		print "**********uniqueness or left-co-ordinated coretarget=$coretarget daughter=$daughter func(daughter)=$func[$daughter], eye=$eye w/ daughters $daughters[$eye]\n";
#		$daughter =$1;
		if ($func[$daughter] eq $func[$i] || $func[$i] =~ /$func[$daughter]$/ && $lines[$i] =~ / (VN|<vn>) /) { # exception: Der er ingen store armbevægelser, ingen føren sig frem ved café-diskene
		    $dep[$i] =$daughter; # link later CJT to first CJT
		    $depchain[$i] .= " " . $daughter . $depchain[$daughter];
		    $daughters[$daughter] .= " " . $target . "-CJT" . $i;
		    $offspring[$daughter] .= " " . $target . "-CJT" . $i;
		    if ($offspring[$i]) {$offspring[$daughter] .= " " . $offspring[$i];}
#		print "||***i=$i target=$target head=$eye daughters(eye)=$daughters[$eye] dep(i) =$dep[$i] cjt-head=$daughter\n";
#		    $lines[$i] =~ s/\]/\] <cjt>/;
		    $cjti =$i; &addcjt;
		    return;
		}
	    }
	    elsif ($target =~ /^\@(ADVL|NPHR)$/ && $lines[$eye] =~ /$target/ && ! ($conditions =~ /\(D\)/)) { # top level coordination of ADVL and NPHR
#		print "***left-co-ordinated target=$target lines(eye)=$lines[$eye]\n";
		$firsttop =$eye;
		$circct=0;
		while ($dep[$firsttop] && $target eq "\@$func[$dep[$firsttop]]" && $circct < 10) {
		  $circct++;
		  $firsttop =$dep[$firsttop];
		}
		$dep[$i] =$firsttop; # link later CJT to first CJT
		if ($depchain[$firsttop]) {$depchain[$i] .= " " . $firsttop . $depchain[$firsttop];}
		else {
		    $depchain[$i] .= " " . $firsttop;
		}
		$daughters[$firsttop] .= " " . $target . $i;
		$offspring[$firsttop] .= " " . $target . $i;
		if ($offspring[$i]) {$offspring[$firsttop] .= " " . $offspring[$i];}
#		print "||***i=$i target=$target head=$eye daughters=$daughters[$eye]\n";
#		$lines[$i] =~ s/\]/\] <cjt>/;
		$cjti =$i; &addcjt;
		return;
	    }
	    elsif ((! $headblockright[$eye] || $target =~ /^\@(ADVL|NPHR|S<)/ || $target =~ /<np-(long|list)>/) && ! ($conditions =~ /\(D\)/ && $dep[$eye])) {
#		print "her+++ $i $target eye=$eye $headblockright[$eye]\n";
		if ($conditions =~ /\(D\)/) {
####
		    $eyefunc="\@$func[$eye]";
#		    print "func=$eyefunc daughters(i)=$daughters[$i]\n";
		    if ($eyefunc =~ /([FSR]?-?SUBJ|ACC|DAT|SC|OC|SA|OA|P<|<quote>|AUX<)/ && $daughters[$i] && $daughters[$i] =~ / $eyefunc([0-9]+)/) {
#		print "***co-ordinated inverse target=$target\n";
			$daughter =$1;
			$eyenow=$daughter;
			$inow=$eye;
#			$lines[$eye] =~ s/\]/\] <cjt>/;
			$cjti =$eye; &addcjt;
		    }
		    else {
			$eyenow=$i; $inow=$eye;
#			$targetnow="\@$func[$eye]";
			if ($lines[$eye] =~ m/(\Q$head\E)/) {
			  $targetnow="$1";
			}
			else {
			  $targetnow = ""; # problem, this line only to prevent undefined targetnow in previous line
#			  print "--missing targetnow\n";
			}
			$tabuheads[$i] .= " $eye "; # så fx relativsætning ikke går i stå i sit eget subjekt
		    }
#		    print "***inverse dependency, target=$i $target, eye=$eye $func[$inow]\n";
		    # omvendt dependens betyder at eye er "fuld" - den er jo egentlig dependent og kan kun have en mor
		}
		else {$eyenow=$eye; $inow=$i; $targetnow =$target;}
		$dep[$inow] =$eyenow;
		if ($depchain[$eyenow]) {$depchain[$inow] .= " " . $eyenow . $depchain[$eyenow];} # depchain hele vejen op
		else {$depchain[$inow] = " " . $eyenow . " ";}
#		if ($depchain[2]) {print "----------i=$i eye=$eye depchain[2]=$depchain[2]\n";}

		if ($daughters[$inow]) {
#		    print "---$inow-daughters $daughters[$inow]\n";
		    @daughterlist =split / /,$daughters[$inow];
		    foreach (@daughterlist) {
			s/^.*?([0-9]+)( .*)?$/$1/; # cave: some tags (e.g. PCP2) contain a number, too
			if (/[0-9]/) {
			    $depchain[$_] .= $depchain[$inow] ;
			    $depchain[$_] =~ s/  +/ /g;
#			    print "---$_ depchain $depchain[$inow]\n";
			}
		    }
		}
#		print "**inow=$inow->$dep[$inow] eyenow=$eyenow targetnow=$targetnow\n";
		if ($targetnow =~ /<cjt>/) {
		  $targetnow .= "-CJT"; # to prevent uniqueness rule complaining about conjuncts instead of realt func-competitors
		}
		$daughters[$eyenow] .= " " . $targetnow . $inow;
		$offspring[$eyenow] .= " " . $targetnow . $inow;
		if ($offspring[$inow]) {$offspring[$eyenow] .= " " . $offspring[$inow];}
#		print "***i=$i $dep[i] target=$targetnow head=$eye/$eyenow daughters=$daughters[$eyenow] offspring=$offspring[$eyenow] eye-depchain=$depchain[$eye]\n";
		$topeye =0; $circularhead =0; # ingen cirkularitet alligevel, head found further to the left
		return;
	    }
#	    else {print "her+++ $i $target eye=$eye $headblockright[$eye]\n";}

	}
	if ($trans && $lines[$eye] =~ / $trans / && ! ($lines[$eye] =~ /<cjt>/)) {
#	    print "transline=$lines[$eye]\n";
	    $trans ="";
	}

#	if ($lines[$eye] =~/FS/ && $daughters[$eye]) {print "***i=$i eye=$eye daughters=$daughters[$eye] barrier=$barrier  lines[$eye]=$lines[$eye]\n";}

### the following jump is done before barrier-testing, meaning that PR|IMPF won't trigger the barrier - which is ok as long as the jump goes all the way to subclause start .... the section would maybe have to be altered for other languages, that don't have obligatory subject left of subclaus finite verb (looking, for instance, for <clb> directly)
	if ($lines[$eye] && $lines[$eye] =~ /\@FS-\@(<|[NAP]<)/ && $daughters[$eye] && $daughters[$eye] =~ /\@[FSR]?\-?SUBJ>([0-9]+)/ && $1 && $1 < $eye && ($neweye=$1) && ! ($lines[$i] =~ / \@(N<|N<PRED|APP)/)) {
#	    print "***jumping for $i: fra $eye\n";
	    $eye =$neweye; # jumping to the start of subclause
	    while (! ($lines[$eye] =~ /<clb>/) && $lines[$eye-1] && $lines[$eye-1] =~ /\@(SUB|ACC>|SC>|ADVL>|SA>|>>P|>N|>A) /) {
		$eye--;
	    }
#	    print "***jumping for $i: neweye $eye\n";
	}
	elsif ($eye > 0 && $barrier && $lines[$eye] =~ / $barrier /) {$barrier =""; return;}

    }
    if ($dep[$i] ==0 && $topeye) { # i.e. no head found
#	print "***assigning circular cave: topeye=$topeye, i=$i rerun=$rerun\n";
	$tabuheads[$topeye] .= " " . $i . " ";
	$dep[$topeye] =0;
	$dep[$i] =$circularhead;
	$topeye =0;
	$rerun =1;
    }
}

sub findheadright() {
#    my $eye;
  $rightloops =0;
    for ($eye =$i+1; $eye <=$num && $rightloops < 100; $eye++) {
      $rightloops++; # endless loop precaution
#      print "--here $eye\n";
	if ($lines[$eye] =~ /(\@PAR-L|<pu-left>)/) { # skal have PAR-R tag, otherwise oddities like )( give problems
	    while (! ($lines[$eye] =~ /(PAR-R|<pu-right>)/) && $eye >0 && $eye < $num) {$eye++;}
	}
	elsif ($lines[$eye] =~ /\$\(/) {
	    while (! ($lines[$eye] =~ /\$\)/) && $eye <$num) {$eye++;}
	}
	elsif ($lines[$eye] =~ /\@FOC>/ && $dep[$eye] && $lines[$dep[$eye]] =~ /\@CO/ && $dep[$dep[$eye]] && $dep[$dep[$eye]] > $eye) { # dels ... dels, både ... og
#	    print "------$eye changed to $dep[$dep[$eye]]\n";
	    $eye =$dep[$dep[$eye]];
	}
#	print "--i=$i ?target=$target  eye=$eye ?$head rule $ruleid{$target}[$j]\n";
#	if ($depchain[$eye]) {print "-------$depchain[$eye]\n";}

	if ($lines[$eye] =~ / $head / && (! $depchain[$eye] || ! ($depchain[$eye] =~ / $i /)) && (! $tabuheads[$i] || ! ($tabuheads[$i] =~ / $eye /)) && (! $headchild || $daughters[$eye] && $daughters[$eye] =~ / $headchild/) && (! $nothead || ! ($lines[$eye] =~ / $nothead /)) && ! $trans) {
#	if ($lines[$eye] =~ / $head / && (! $depchain[$eye] || ! ($depchain[$eye] =~ / $i /)) && (! $tabuheads[$i] || ! ($tabuheads[$i] =~ / $eye /)) && (! $headchild || $daughters[$eye] && $daughters[$eye] =~ / $headchild/) && (! $nothead || ! ($lines[$eye] =~ / $nothead /)) && ! ($target =~ /SUBJ>/ && $lines[$eye] =~ /\@N</) && ! $trans) {

	    if ($test) {print "--*2*--i=$i eye=$eye target=$target rule $ruleid{$target}[$j]\n";}
#	    if ($tabuheads[$i]) {print "     tabu[i]=$tabuheads[$i]\n";}

	    if (($target =~ /\@<?(SUBJ|R-<?SUBJ|ACC|DAT|SC|OC|SA|OA|P<|<quote>|AUX<)/ || $target =~ /\@<?ADVL/ && $daughters[$i] && $daughters[$i] =~ /<co-advl>/ || $target =~ /\@<?PRED/ && $daughters[$i] && $daughters[$i] =~ /<co-pred>/) && $daughters[$eye] && $daughters[$eye] =~ / $target([0-9]+)/) {
#		print "***right-co-ordinated target=$target i=$ieye=$eye daughters(eye) =$daughters[$eye]\n";
		$daughter =$1;
		$dep[$i] =$daughter; # link later CJT to first CJT
#		$lines[$i] =~ s/\]/\] <cjt>/;
		$cjti =$i; &addcjt;
#		$depchain[$i] .= " " . $daughter . $depchain[$daughter];
		$depchain[$i] .= " " . $daughter . " ";
		$daughters[$daughter] .= " " . $target . "-CJT" . $i;
		$offspring[$daughter] .= " " . $target . "-CJT" . $i;
		if ($offspring[$i]) {$offspring[$daughter] .= " " . $offspring[$i];}
	    }
	    elsif ($unattached) {
	      $dep[$i] =$eye;
	      $daughters[$eye] .= " $func[$i]$i";
	    }
	    else {
	      if ($conditions =~ /\(D\)/) {$inow =$eye; $eyenow =$i} # inverse dependency
	      else {$inow =$i; $eyenow =$eye;}
		$dep[$inow] =$eyenow;
	      if ($target =~ /<co-/) {
#		print "--inow=$inow, eyenow=$eyenow\n";
#		    $lines[$eyenow] =~ s/\]/\] <cjt>/;
		    $cjti =$eyenow; &addcjt;
		}
		$depchain[$inow] .= " " . $eyenow . " ";
		if ($daughters[$inow]) {
#		    print "---$inow-daughters $daughters[$inow]\n";
		    @daughterlist =split / /,$daughters[$inow];
		    foreach (@daughterlist) {
			s/^.*?([0-9]+)$/$1/;
			if (/[0-9]/) {
			    $depchain[$_] .= $depchain[$inow] ;
			    $depchain[$_] =~ s/  +/ /g;
#			    print "---$_ depchain $depchain[$inow]\n";
			}
		    }
		}

		$daughters[$eyenow] .= " " . $target . $inow;
		$offspring[$eyenow] .= " " . $target . $inow;
		if ($offspring[$inow]) {$offspring[$eyenow] .= " " . $offspring[$inow];}
#		print "***target=$target i=$inow head=$eyenow daughters=$daughters[$eyenow] depchain $depchain[$eyenow]\n";
	    }
	    return;
	}
	if ($trans && $lines[$eye] =~ / $trans/) {
	    $trans ="";
#	    print "--$target $head" . " $i->$eye trans=$trans\n";
	}
#	print "--$target $head" . " $i->$eye\n";
	if ($barrier && $lines[$eye] =~ / $barrier /) {$barrier =""; return;}
	if ($target =~ /[\@\|]((SUBJ|ADVL|PRED|ACC|DAT|PIV|SC|OC|SA|OA)\)?>|SUB|>>P)/ && ! ($target =~ /\@(ACC|SC|SUBJ)>>/) && $lines[$eye] =~ /(\@SUB|<rel>|<interr>|<clb\??>) /) { # skal ikke gælde <co-...> # |\@SUBJ>|\@[FS]-SUBJ> removed, otherwise SUB e.g. is prevented from finding its VFIN-head, because it is followed by a SUBJ> which will jump to MV, across AUX-VFIN
#	    print "--eye=$eye dep=$dep[$eye] cross embedded clause (target=$i:$target) rule $ruleid{$target}[$j] dep2=$dep[$dep[$eye]] dep3=$dep[$dep[$dep[$eye]]]\n";

	    while ($dep[$eye] && $dep[$eye] >0 && $dep[$eye] > $eye && ! ($lines[$eye] =~ /-\@/)) { # cave: @FS-ADVL>, e.g., shouldn't jump, only ordinary @ADVL>
		if ($test) {print "-----*3*--eye=$eye dep=$dep[$eye] cross embedded clause (target=$i:$target)\n";}
		$eye =$dep[$eye]; # jump across embedded clauses, i.e. til main verb, or - for SUB and SUBJ - to finite verb
	    }
	    if ($lines[$eye] =~ / (\@FS[^ ]+)/ && ($funclocal=$1) && $daughters[$eye] =~ /$funclocal([0-9]+)/) { # jump further to possible coordinated finite verb
		if ($1 > $eye) {$eye =$1;}
		if ($test) {print "-----*3*--eye=$eye dep=$dep[$eye] cross embedded clause (target=$i:$target)\n";}
	    }
	}
	if ($lines[$eye] =~ /PRP/ && ! ($lines[$eye] =~ /(<prp-stray>|<prp-strand>)/) && ! ($lines[$eye] =~ / $head /) && ! ($target =~ /\@(ACC|SC|SUBJ)>>/) && $daughters[$eye] && $daughters[$eye] =~ /\@P<([0-9]+)/ && $1 && $1 > $eye) {
	    if ($test) {print "---*4*--prp at $eye -> $1 for i=$i\n";}
	    $eye =$1; # jump across pp
	}
	if ($lines[$eye] =~ /\@ADVL>A/ && $dep[$eye] && $dep[$eye] > $eye) { # jumping @ADVL>A -- ADJ PART bracket, especially in German
	    if ($test) {print "---*5---advl>a at $eye -> $dep[$eye] for i=$i\n";}
	    $eye =$dep[$eye]; # jump across pp
	}
#	if ($test && $i==1) {print "--***$i head=$head ... now eye $eye\n";}
    }
}

sub print {
    for ($i =1; $i <=$num; $i++) {
      $line =$lines[$i];
#      print "--$line\n";
#	if ($line =~ /<co-/) {print "$i-$dep[$i]-$dep[$dep[$i]]\n";}
	if ($line =~ /(<co-|\@CO)/ && ! ($line =~ /<adv>/) && $dep[$i] && $dep[$i] > $i && $lines[$dep[$i]] =~ /<cjt>/ && $dep[$dep[$i]]) {
#	    print "---her co-raising i=$i dep=$dep[$i] dep(dep)=$dep[$dep[$i]] $line daughters[dep[i]]=$daughters[$dep[$i]]\n";
	    if ($daughters[$dep[$dep[$i]]] && ! ($daughters[$dep[$dep[$i]]] =~ /SUBJ/) && $daughters[$dep[$i]] && ! ($line =~ /<co-subj>/) && $lang =~ /da/) { # only real SUBJ> -> VFIN dependencies, cave SUBJ> -> SUBJ> dependencies (therefore ! <co-subj>)
		while ($daughters[$dep[$i]] =~ s/ *([FSR]?-?<?SUBJ>?)([0-9]+)//) {
		    $dep[$2] =$dep[$dep[$i]];
		    $daughters[$dep[$dep[$i]]] .= " $1$2";
		}
	    }
	    $dep[$i] = $dep[$dep[$i]] ;
	}
	if ($line =~ /\@[^ ]*SUBJ/ && $dep[$i] && $lines[$dep[$i]]) {$lines[$dep[$i]] =~ s/<nosubj> //;}

    }

#    if ($livesent) {
      print "\n<ß>\n"; $betaopen =1;
#    }
    if ($_) {
      s/(<\/s>)/<\/ß>\n$1/;
      if (/<\/ß>/) {$betaopen =0;}
    }

    for ($i =1; $i <=$num; $i++) {
	$line =$lines[$i];

### aux-raising @ADVL> to <mv> (but NOT subjects and @SUB or @INFM and <cjt>-verbs or top level conjuncts, and not co-ordinators, and not Portuguese @PRT-AUX<)

	if ($dep[$i] && $lines[$dep[$i]] =~ /<aux>/ && ! ($lines[$i] =~ /(\@(AUX<|PRT-AUX<|[FSR]?-?<?SUB|INFM|CO|STA|QUE|EXC)|<cjt>|<co-|<adv>.*KC)/)) {
	    $j =$dep[$i];
#	    print "$daughters[$j]\n";
	    while ($daughters[$j] && $daughters[$j] =~ m/\@AUX<([0-9]+)/ && ($auxdaughter=$1) && ! ($lines[$auxdaughter] =~ /<cjt>/)) { # has to be \@AUX<, not just AUX<, to exclude PRT-AUX<
	      $j =$auxdaughter;
	    }
	    $dep[$i] =$j;
	}


### ICL-OC/OA before FS-ACC

	if ($lines[$i] =~ /FS-\@<ACC/ && $lines[$dep[$i]] && $lines[$dep[$i]] =~ /ICL-\@<OA/) {
#	    print "----func(i)=$func[$i] func(dep(i))=$func[$dep[$i]] daughters(dep(dep(i)))=$daughters[$dep[$dep[$i]]]\n";
	    $daughters[$dep[$dep[$i]]] =~ m/<ACC([0-9]+)/; $acc =$1;
	    if  (! $acc || $acc == $i) {
		$dep[$i] =$dep[$dep[$i]]; # Hun fik ofte at vide, at hun havde ... [da74]
	    }
	}

	$line =~ s/^ //;
	$line =~ s/ \[/\t\[/g;
	$line =~ s/-\@/-/g; # normalise clause function
	$line =~ s/(<cjt> )(<cjt> )+/$1/g;
	$line =~ s/(<cjt-head>.*\t.*\] )/$1<cjt-head> /; # propagating <cjt-head> to a possible second cohort line
	$line =~ s/(<cjt>.*\t.*\] )/$1<cjt> /; # propagating <cjt> to a possible second cohort line

	if (! ($line =~ /<[0-9]+>.*<C:/) && $line =~ s/^(\$[,\.;\?\!\)\(\-]) */$1/ || ($line =~ /^\-[0-9]/) && $line =~ s/^(\$[,\.;\?\!\)\(\-]).*/$1/) {$dep[$i] =0;} # re-zero punctuation dependencies used for coordination, plus removing their PU @CO etc ... doing this, however, might not always be desirable
	if (! $dep[$i]) {$dep[$i] =0;}
	print "$line #$i->$dep[$i]\n";
    }
    if ((! $_ || /^$/) && ! $betaopen) {print "</ß>\n"; $betaopen=0;}
#    print "--her: $_...\n";
#    print "\n"; # added to separate sentences before addframes --> problem: creates space before </s> / </ß>
}

### unused subroutine: YES - for reruns efter circularity, where the problem-top is assigned zero dependency
sub token_driven_dependency {
    for ($i =1; $i <=$num; $i++) {
	if (! $dep[$i] && $lines[$i] =~ /\@/) {
#	    print "--no dep for $i\n";
	    if ($rerun && $rerun ==2) {
#		print "***rerun $i\n";
	    }
	    if (! $rerun || $rerun==1) {$depchain[$i] = " ";}
	    $line =$lines[$i];
	    foreach (@targets) {
		$target =$_;
#		print "---i=$i target=$_ line=$line***\n";
		if ($line =~ / (\@[&\#]?(FS|ICL|AS)-)?$target /) {
#		print "***target=$_ " . " line=$line***\n";
		    for ($j =1; $j <= $ct{$target}; $j++) {
			$conditions =$rules{$target}[$j];
#		    print "her: $conditions\n";
			if ($conditions =~ /HEADCHILD=(\(.*?\))/) {
			    $headchild =$1;
			    $headchild =~ s/,/\|/g;
#			    print "***headchild-condition=$headchild\n";
			}
			else {$headchild ="";}
			if ($conditions =~ /NOTHEAD=(\(.*?\))/) {
			    $nothead =$1;
			    $nothead =~ s/,/\|/g;
#			    print "***nothead-condition=$nothead\n";
			}
			else {$nothead ="";}
			if ($conditions =~ /NOTTARGET=(\(.*?\))/) {
			    $nottarget =$1;
			    $nottarget =~ s/,/\|/g;
#			    $nottarget =~ s/-\@/-/g;
			    if ($line =~ / $nottarget /) {
#			    print "***target=$target nottarget-condition=$nottarget $line rule $ruleid{$target}[$j]\***\n";
				goto nomorerules3;
			    }
			}
			else {$nottarget ="";}
			if ($conditions =~ /TRANS:(\(.*?\))/) {
			    $trans =$1;
			    $trans =~ s/,/\|/g;
#			    print "***trans-condition=$trans\n";
			}
			else {$trans ="";}
			if ($conditions =~ /BARRIER:(\(.*?\))/) {
			    $barrier =$1;
			    $barrier =~ s/,/\|/g;
#			    print "***barrier-condition=$barrier\n";
			}
			else {$barrier ="";}
			$head =$heads{$target}[$j];
#			print "###i=$i target=$target head=$head conditions=$conditions\n";
			if ($conditions =~ /^\(L/) {
			    &findheadleft;
			}
			elsif ($conditions =~ /^\(R/) {
			    &findheadright;
			}
			else {
			    &findheadleft;
			    &findheadright;
			}
		    }
		  nomorerules3:
		}
	    }
	}
    }
    return;
}

sub addcjt {
#    print "i=$i cjti=$cjti eye=$eye target=$target conditions=$conditions\n";
    $lines[$cjti] =~ s/\] /\] <cjt> /;
}

sub addcjthead {
  for ($i =1; $i <=$num; $i++) {

    $line = $lines[$i];
#      print "**her $i $dep[$i] $line\n";
### switching first and second conjunct for subjects - it already works for ADVL>, god knows why ...
    if ($lines[$i] =~ /<cjt>.*(SUBJ>|@[FS]-SUBJ>)/ && $lines[$dep[$i]] =~ /(\@SUBJ>|@[FS]-SUBJ>)/ && $dep[$i] > $i) {
      if (! ($lines[$dep[$i]] =~ /<cjt>/)) {$lines[$dep[$i]] =~ s/\] /\] <cjt> /;}
      $outerhead =$dep[$dep[$i]];
      $dep[$dep[$i]] =$i;
      $dep[$i] =$outerhead;
      $lines[$i] =~ s/<cjt>/<cjt-head>/;
    }

    elsif ($line =~ /<co-vp>/) {
#	  print "--***** $line ... $dep[$i]\n";
      $lines[$dep[$i]] =~ s/\] /\] <vpcjt> /;
      if ($lines[$i-1] =~ /<(aux|mv)>.* (\@[^ \n]+)/ && ($newfunction =$2) && ! ($dep[$i] == $i-1)) {
	$daughters[$dep[$dep[$i]]] =~ s/ [^ ]+$dep[$i]//;
	$dep[$dep[$i]] =$i-1;
	$lines[$dep[$i]] =~ s/ \@[^ \n]+/ $newfunction/;
	$daughters[$dep[$dep[$i]]] .= " " . $newfunction . $dep[$i];
      }
      $lines[$dep[$dep[$i]]] =~ s/\] /\] <vpheadcjt> /;
    }

    elsif ($lines[$i] =~ /(<cjt>|\@CO)/ && ! ($line =~ /<adv>/) && $dep[$i] && $lines[$dep[$i]] =~ /<cjt>/) { # raises conjuncts and (cg.attach-unmarked) coordinators to the first, rather than a later conjunct in a conjunct chain
#	  print "raising $i $dep[$i] $dep[$dep[$i]]\n";
      if ($dep[$dep[$i]]) {
	$cjtct=0;
	while ($lines[$dep[$i]] =~ /<cjt>/ && $dep[$dep[$i]] && $cjtct < 5) {
	  $dep[$i] = $dep[$dep[$i]]; # flat coordination, but more stable in trees
	  $cjtct++; # endless loop protection
	}
      } # if grandmother is not top/0
      else {
	#	      $lines[$i] =~ s/\@CO/\@AX/;
	$lines[$i] =~ s/\] /] <nofirstcjt> /;
	$lines[$dep[$i]] =~ s/ <cjt>//g; # can't coordinate if there's no first conjunct ..., e.g. "e se tiverem qualquer problema, ..."
      }
    }
    if ($lines[$i] =~ /<cjt>/ && ! ($line =~ /<xxxvpcjt>/) && $dep[$i] && ! ($lines[$dep[$i]] =~ /<cjt-head>/)) { # why not <vpcjt>? --> blocked with xxx
      $lines[$dep[$i]] =~ s/\] /\] <cjt-head> /;
#	    print "---i=$i, cjt-head = $dep[$i] $lines[$dep[$i]]\n";
    }
    if ($line =~ /<cjt.* (PR|IMPF|PS|MQP|PS\/MQP|FUT|COND|VFIN) / && ! ($line =~ /<vpcjt>/) && $dep[$i] && $lines[$dep[$i]] =~ /<(mv|aux)>/) {
      if (! $daughters[$i] || ! ($daughters[$i] =~ /SUBJ/)) {
	$lines[$i] =~ s/\] /\] <nosubj> /;
	if ($daughters[$dep[$i]] && $daughters[$dep[$i]] =~ /SUBJ/) {
	  $lines[$dep[$i]] =~ s/\] /\] <predco> /;
	}
	else {
	  $lines[$dep[$i]] =~ s/\] /\] <nosubj> /;
	}
      }
    }
  }
}

sub nplongadapt {
    for ($i =1; $i <=$num; $i++) {
	if ($lines[$i] =~ /<np-long>/ && $dep[$i] && ! ($lines[$dep[$i]] =~ /<np-disc>/) && $daughters[$dep[$i]]) {
#	    print "**---i=$i head-daughters: $daughters[$dep[$i]]\n";
	    @daughterlist = split / /,$daughters[$dep[$i]];
	    $npclose =0;
	    foreach (@daughterlist) {
		m/[^0-9]([0-9]+)$/;
		$daughter =$1;
#		print "-----$_ daughter: $daughter\n";
		if ($daughter && $lines[$daughter] =~ /<np-close>/ && $daughter < $i) {
		    $npclose =1;
#		    print "---$daughter $lines[$daughter]\n";
		}
	    }
#	    if ($lines[$dep[$i]] =~ /<np-disc>/) {$npdisc =1;}
	    if (! $npclose && ! ($lines[$dep[$i]+1] =~ /<np-close>/) && $dep[$dep[$i]] && ! ($lines[$dep[$dep[$i]]] =~ /<mv>/)) { # the <np-long> may have been attached not to the common mother shared with <np-close>, but to a dependent of the latter, which hence won't be visible in <np-long>'s mother's daughterlist: "de aldersgrupper <np-close> mellem 30 og 60 år, som især efterspørger <np-long> FS-N< ejerboliger" .... # <np-close>-check as a last safety catch, since daughters aren't completely sorted in this program. If it doesn't work, check all daughters of $dep[$i], og insert a sorting program --> now all daughters checked
		$j =$dep[$i];
		while ($j > 1 && $dep[$j] && ! ($lines[$dep[$j]] =~/\@(N<|N<PRED|APP|FS-\@N<|(SUBJ|ACC|DAT|SC|OC|SA|OA)>|<mv>)/)) {
#		    print "---now j=$j $lines[$dep[$j]]\n";
		    $j--;
		}
		$dep[$i] = $dep[$dep[$j]];
	    }
	}
    }
}

sub circularcheck {
    $depnul =0;
    for ($i =1; $i <=$num; $i++) {
#	print "--circularcheck $i  $lines[$i]\n";
	$lines[$i] =~ s/( \@[^ \n]+)\1/$1/; # double identical functions ?? (@CO @CO)
	if ($lines[$i] =~ / \@.* \@/ && ! ($lines[$i] =~ /\] .*\] /)) {
#	    print "--checking syn-doubles $i $lines[$i]\n";
#	    if ($dep[$i]) {print "--daughters(dep($i)) $daughters[$dep[$i]]\n";}
	    if ($dep[$i] && $daughters[$dep[$i]] =~ /\@<?SUBJ.*\@<?SUBJ/) {
#		print "--removing reading from $i\n";
		$lines[$i] =~ s/ \@<?SUBJ>?//; $ambi =1;
	    }
	    elsif ($dep[$i] && $daughters[$dep[$i]] =~ /\@<?ACC.*\@<?ACC/) {
		$lines[$i] =~ s/ \@<?ACC>?//; $ambi =1;
	    }
	    elsif ($dep[$i] && $daughters[$dep[$i]] =~ /\@<?SC.*\@<?SC/) {
		$lines[$i] =~ s/ \@<?SC>?//; $ambi =1;
	    }
	}
	if ($lines[$i] =~ /\@/ && $dep[$i] ==0) {$depnul =$i;}
	$j =$i;
	$depis= " ";
	$depth =0;
	while ($dep[$j] && ! ($depis =~ / $j /)  && $depth < 30) {
	    $depis .= "$j ";
	    $j =$dep[$j];
	    $depth++;
	}
	if ($j == $i && $dep[$j] > $i) {
	    print "-- circularity at $i->$dep[$i] depth=$depth depis=$depis\n";
	    $circularity .= " $i";
	    $tabuheads[$dep[$i]] .= " " . $i . " "; # -> @tabuheads is the only array that survives between circularity reruns, forcing the right edge loop-dep[i] to look further left than the left edge loop-i --> makes the cruder solution below superfluous, since ultimately, zero-attachment will result (further bonus, @ function can be maintained)

#	    if (! $depnul) {$dep[$i] =0;}
#	    else {$dep[$i] =$depnul;}
#	    $lines[$i] =~ s/ \@F?-?<?(SUBJ|S-<?SUBJ|ACC|DAT|PRED|APP|N<PRED|SC|OC|P<|>>P)>?/ \@NPHR/;
#	    $lines[$i] =~ s/ \@<?(ADVL|SA|OA|PIV)>?/ \@ADVL/;
#	    $lines[$i] =~ s/ \@FS-\@<?(ADVL|SA|OA|PIV|P<)>?/ \@FS-\@STA/;
#	    if ($daughters[$dep[$i]]) {$daughters[$dep[$i]] =~ s/ $i//;}
	}
    }
}
