#!/usr/bin/perl -w use strict; sub UNK() { 0; } sub LTE() { 1; } sub GTE() { 2; } sub EQU() { 3; } my $Pref= {}; my %OpBits= ( '<' => LTE(), '>' => GTE(), '=' => EQU(), ); my %RevBits= ( UNK() => UNK(), LTE() => GTE(), GTE() => LTE(), EQU() => EQU(), ); Main( @ARGV ); exit( 0 ); sub onePref { my( $x, $bits, $y )= @_; return if $bits == UNK(); if( $Pref->{$x} && exists $Pref->{$x}{$y} ) { die "ERROR contradictory $x $y\n" if $Pref->{$x}{$y} != $bits; } else { $Pref->{$x}{$y}= $bits; $Pref->{$y}{$x}= $RevBits{$bits}; } } sub allPrefs { my( $x, $c, $y )= @_; my $bits= $OpBits{$c}; $Pref->{$x}{$x}= $Pref->{$y}{$y}= EQU(); onePref( $x, $bits, $y ); while( my($z,$v)= each %{$Pref->{$y}} ) { onePref( $x, $bits & $v, $z ); } $bits= $RevBits{$bits}; while( my($z,$v)= each %{$Pref->{$x}} ) { onePref( $y, $bits & $v, $z ); } } sub partialOrder { for my $chain ( @_ ) { while( $chain =~ /\G\s*(\w+)\s*([<=>])\s*(?=(\w+))/gc ) { my( $x, $c, $y )= ( $1, $2, $3 ); allPrefs( $x, $c, $y ); } if( $chain !~ /\G\s*(\w+)\s*$/g ) { die "Invalid preferences ($chain).\n"; } } } sub compare { my( $x, $y )= @_; return $Pref->{$x}{$y} || UNK(); } sub Main { partialOrder( 'xx < yy < zz > aa', 'bb < yy = aa > cc', ); my @vals= sort keys %$Pref; my %bitVal= ( UNK() => '.', LTE() => '-', GTE() => '+', EQU() => '=', ); my $len= 1; for( map length($_), @vals ) { $len= $_ if $len < $_; } for my $v ( @vals ) { $v= sprintf "%-*s", $len, $v; } print "Comparison Table:\n"; print join " ", ' 'x$len, @vals; print $/; for my $x ( @vals ) { print "$x "; for my $y ( @vals ) { my $c= compare( $x, $y ); printf "%-*s", 1+$len, $bitVal{$c}; } print "\n"; } partialOrder( 'ww < ww' ); }