http://qs321.pair.com?node_id=1068370

slinky773 has asked for the wisdom of the Perl Monks concerning the following question:

OK, here goes:

I'm making this final exam study guide program for my Geometry Honors class in perl as a command line script because I'm too lazy to figure out how to make a GUI. I was on Unit 3, which is logic. We had a lot of assignments where you had to use the chain rule and law of detachment (take all the contrapositives of the statements, basically) to take, say, 4 statements like '~c->~f', 'g->b', 'p->f', and 'c->~b' and you had to derive that ultimately 'p->~g' was the correct conclusion. So I typed this subroutine up in a module:

sub LHCC { DECISION: print " Hi. This is the Lee-Hardy Conclusion Calculator.\n Given a series of statements using the syntax\n 'p -> q', I will deduce the correct conclusion\n to be made using basic logic and the chain rule.\n Type 'ready' when you are ready to input your statements.\n Type 'quit' to exit the LHCC.\n\n"; my $decision = <STDIN>; chomp $decision; if($decision =~ /quit/i) {if(! &Unit3()) {return 0;}} elsif($decision =~ /ready/i) {} else {print "\nCould not interpret, try again.\n"; goto DECISION;} print "\nHow many statements will be used?\n\n"; my $NumberOfStatements = <STDIN>; chomp $NumberOfStatements; if($NumberOfStatements !~ /^-?\d+\.?\d*$/) {print "\nCould not int +erpret, try again.\n"; goto DECISION;} print "\nOnly a hypen will be accepted for 'not'.\n BTW, with many statements with syntax p -> q, you can't\n have duplicate q's. Sorry. Hey, I only had a week to make\n this thing.\n\n"; print "Given the statements "; my $StatementNumber = 0; my $P = 0; my $Q = 0; my %Statements = (); for $StatementNumber (1..$NumberOfStatements) { if ($StatementNumber != $NumberOfStatements) {print "P$Stateme +ntNumber -> Q$StatementNumber, ";} elsif ($StatementNumber == $NumberOfStatements) {print "and P$ +StatementNumber -> Q$StatementNumber,\n\n";} else {die "Whut? Something weird just happened, you aren't sup +posed to be able to see this. Run again and if the error persists, em +ail me at yflee7\@students.d125.org.\n";} } for $StatementNumber (1..($NumberOfStatements*2)) { if($StatementNumber % 2 == 0) { my $TrueStatementNumber = $StatementNumber/2; print "Q$TrueStatementNumber = "; $Q = <STDIN>; chomp $Q; if (! $Q) {print "\nCould not interpret, try again\n"; got +o DECISION;} print "\n"; $Statements{"Q$TrueStatementNumber"} = $Q; } elsif($StatementNumber % 2 != 0) { my $TrueStatementNumber = int($StatementNumber/2) + 1; print "P$TrueStatementNumber = "; $P = <STDIN>; chomp $P; if (! $P) {print "\nCould not interpret, try again\n"; got +o DECISION;} print "\n"; $Statements{"P$TrueStatementNumber"} = $P; } else {die "Whut? Something weird just happened, you aren't sup +posed to be able to see this. Run again and if the error persists, em +ail me at yflee7\@students.d125.org.\n";} } my %Contrapositives = (); for $StatementNumber (1..$NumberOfStatements) { $Contrapositives{"P$StatementNumber"} = $Statements{"Q$Stateme +ntNumber"}; $Contrapositives{"Q$StatementNumber"} = $Statements{"P$Stateme +ntNumber"}; } my @ContrapositivesKeys = keys %Contrapositives; for my $Element (@ContrapositivesKeys) { my $ToTildeOrNotToTilde = substr $Contrapositives{$Element}, 0 +, 1; my $RestOfStatement = substr $Contrapositives{$Element}, 1; if($ToTildeOrNotToTilde eq '-') { $Contrapositives{$Element} = $RestOfStatement; } elsif($ToTildeOrNotToTilde ne '-') { $Contrapositives{$Element} = "-" . $Contrapositives{$Eleme +nt}; } else {die "Whut? Something weird just happened, you aren't sup +posed to be able to see this. Run again and if the error persists, em +ail me at yflee7\@students.d125.org.\n";} } @ContrapositivesKeys = keys %Contrapositives; my @StatementsKeys = keys %Statements; for my $Element (1..$NumberOfStatements) { $Statements{$Statements{"P$Element"}} = $Statements{"Q$Element +"}; delete $Statements{"Q$Element"}; delete $Statements{"P$Element"}; } for my $Element (1..$NumberOfStatements) { $Contrapositives{$Contrapositives{"P$Element"}} = $Contraposit +ives{"Q$Element"}; delete $Contrapositives{"Q$Element"}; delete $Contrapositives{"P$Element"}; } my @Conclusion = (); my @OtherConclusion = (); my $KeyValueToCheck = 0; my $key = 0; foreach $KeyValueToCheck (keys %Statements) { if(!$KeyValueToCheck) {die "Whut? Something weird just happene +d.";} my @PossibleConclusion = ($KeyValueToCheck, $Statements{$KeyVa +lueToCheck}); CHECKPOINT: foreach $key (keys %Statements) { if(!$key) {die "Whut? Something weird just happened.";} if($key eq $Statements{$KeyValueToCheck}) { push @PossibleConclusion, $Statements{$key}; $KeyValueToCheck = $key; } elsif($key ne $Statements{$KeyValueToCheck}) {} else {die "Whut? Something weird just happened, you aren't + supposed to be able to see this. Run again and if the error persists +, email me at yflee7\@students.d125.org.\n";} } foreach $key (keys %Contrapositives) { if($key eq $Statements{$KeyValueToCheck}) { push @PossibleConclusion, $Statements{$key}; $KeyValueToCheck = $key; goto CHECKPOINT; } elsif($key ne $Statements{$KeyValueToCheck}) {} else {die "Whut? Something weird just happened, you aren't + supposed to be able to see this. Run again and if the error persists +, email me at yflee7\@students.d125.org.\n";} } if (scalar @PossibleConclusion > scalar @Conclusion) {@Conclus +ion = @PossibleConclusion;} elsif (scalar @PossibleConclusion == scalar @Conclusion) {@Oth +erConclusion = @PossibleConclusion;} elsif (scalar @PossibleConclusion < scalar @Conclusion) {} else {die "Whut? Something weird just happened, you aren't sup +posed to be able to see this. Run again and if the error persists, em +ail me at yflee7\@students.d125.org.\n";} } foreach $KeyValueToCheck (keys %Contrapositives) { if(!$KeyValueToCheck) {die "Whut? Something weird just happene +d.";} my @PossibleConclusion = ($KeyValueToCheck, $Statements{$KeyVa +lueToCheck}); CHECKPOINT2: foreach $key (keys %Statements) { if($key eq $Contrapositives{$KeyValueToCheck}) { if(!$key) {die "Whut? Something weird just happened."; +} push @PossibleConclusion, $Statements{$key}; $KeyValueToCheck = $key; } elsif($key ne $Contrapositives{$KeyValueToCheck}) {} else {die "Whut? Something weird just happened, you aren't + supposed to be able to see this. Run again and if the error persists +, email me at yflee7\@students.d125.org.\n";} } foreach $key (keys %Contrapositives) { if($key eq $Contrapositives{$KeyValueToCheck}) { if(!$key) {die "Whut? Something weird just happened."; +} push @PossibleConclusion, $Statements{$key}; $KeyValueToCheck = $key; goto CHECKPOINT2; } elsif($key ne $Contrapositives{$KeyValueToCheck}) {} else {die "Whut? Something weird just happened, you aren't + supposed to be able to see this. Run again and if the error persists +, email me at yflee7\@students.d125.org.\n";} } if (scalar @PossibleConclusion > scalar @Conclusion) {@Conclus +ion = @PossibleConclusion;} elsif (scalar @PossibleConclusion == scalar @Conclusion) {@Oth +erConclusion = @PossibleConclusion;} elsif (scalar @PossibleConclusion < scalar @Conclusion) {} else {die "Whut? Something weird just happened, you aren't sup +posed to be able to see this. Run again and if the error persists, em +ail me at yflee7\@students.d125.org.\n";} } foreach my $ScalarNumber (0..((scalar @Conclusion)-1)) { if ($ScalarNumber != scalar @Conclusion) {print "$Conclusion[$ +ScalarNumber] => ";} elsif ($ScalarNumber == scalar @Conclusion) {print "$Conclusio +n[$ScalarNumber]";} else {die "Whut? Something weird just happened, you aren't sup +posed to be able to see this. Run again and if the error persists, em +ail me at yflee7\@students.d125.org.\n";} } print "\n\nor \n\n"; foreach my $ScalarNumber (0..((scalar @OtherConclusion)-1)) { if ($ScalarNumber != (scalar @OtherConclusion)-1) {print "$Oth +erConclusion[$ScalarNumber] => ";} elsif ($ScalarNumber == (scalar @OtherConclusion)-1) {print "$ +OtherConclusion[$ScalarNumber]";} else {die "Whut? Something weird just happened, you aren't sup +posed to be able to see this. Run again and if the error persists, em +ail me at yflee7\@students.d125.org.\n";} } print "\n\nIn other words, " . $Conclusion[0] . " => " . $Conclusi +on[(scalar @Conclusion)-1] . " or " . $OtherConclusion[0] . " => " . +$OtherConclusion[(scalar @Conclusion)-1] . "\n"; goto DECISION; }

It's a lot of foreach $scalar (keys %Hash) sort of stuff, but that's the best way I could think of to do this. However, every time I run it, I always get an error akin to this:

Use of uninitialized value in print at Unit3.pm line 142, <STDIN> line + 12. Use of uninitialized value in string eq at Unit3.pm line 144, <STDIN> +line 12. Use of uninitialized value in string ne at Unit3.pm line 149, <STDIN> +line 12. Use of uninitialized value in print at Unit3.pm line 142, <STDIN> line + 12. Use of uninitialized value in string eq at Unit3.pm line 144, <STDIN> +line 12. Use of uninitialized value in string ne at Unit3.pm line 149, <STDIN> +line 12.

and that generally drags on for, say, 75 lines or so. The errors start around when my CHECKPOINT label shows up. Every time I try something and I think I've fixed it, this always changes a tiny bit, but still shows up. To make matters worse, it doesn't even work at the end:

Use of uninitialized value $Conclusion[2] in concatenation (.) or stri +ng at Unit3.pm line 203, <STDIN> line 12. c => -b => => or Use of uninitialized value $OtherConclusion[1] in concatenation (.) or + string at Unit3.pm line 210, <STDIN> line 12. Use of uninitialized value $Conclusion[2] in concatenation (.) or stri +ng at Unit3.pm line 214, <STDIN> line 12. f => => -b In other words, c => or f => -b

Which is… pretty bad. Any help would be appreciated. I stayed up till 5 last night trying to figure this out, and I think I may get ulcers!