/* This is the header file for the Dumper module. It is also included by the
Cases, Odometer and Reporter modules. */
/* external functions */
extern void
Write_Matrix(
file stream,
area *area_pointer,
vector_element *facts_head,
court *court_head,
boolean hypothetical,
cardinal number);
extern void
Write_Year_and_Court(
file stream,
kase *case_pointer,
cardinal level);
extern void
Dump_Specification(
file dump_stream,
file log_stream,
case_law_specification case_law,
boolean inputable_latex,
boolean verbose);
/* This is the implementation file for the Dumper module. */
#include <stdio.h>
#include "shyster.h"
#include "cases.h"
#include "dumper.h"
#include "odometer.h"
static void
warning(
file stream,
const string message)
{
Write_Warning_Message(stream, "Dumper", message, Top_Level);
}
static void
write_hierarchy_table(
file dump_stream,
court *court_pointer)
/* Writes a table of courts, with their ranks */
{
boolean same_rank = FALSE;
fprintf(dump_stream, "%s{Hierarchy}\n\n", Heading);
Indent(dump_stream, 1);
fprintf(dump_stream, "\\begin{small}\n");
Indent(dump_stream, 2);
fprintf(dump_stream, "\\begin{trivlist}\\item[]\n");
Indent(dump_stream, 3);
fprintf(dump_stream, "\\begin{tabular}{|r|l|}\\hline\n");
Indent(dump_stream, 4);
fprintf(dump_stream,
"\\multicolumn{1}{|c|}{$c$}&"
"\\multicolumn{1}{c|}{\\it Court\\/}\\\\\\hline\\hline");
/* while there are still courts to list ... */
while (court_pointer != NULL) {
fprintf(dump_stream, "\n");
Indent(dump_stream, 4);
if (!same_rank)
fprintf(dump_stream, "%u", court_pointer->rank);
fprintf(dump_stream, "&%s\\\\", court_pointer->string);
if (court_pointer->next != NULL)
same_rank = (court_pointer->rank == court_pointer->next->rank);
court_pointer = court_pointer->next;
}
fprintf(dump_stream, "\\hline\n");
Indent(dump_stream, 3);
fprintf(dump_stream, "\\end{tabular}\n");
Indent(dump_stream, 2);
fprintf(dump_stream, "\\end{trivlist}\n");
Indent(dump_stream, 1);
fprintf(dump_stream, "\\end{small}\n\n");
}
static void
write_distance(
file stream,
distance_subtype distance,
boolean centre,
boolean rule_at_right)
/* Writes distance as a cell in a table of distances, centred (if centre is
TRUE) and with a vertical rule at the right (if rule_at_right and centre
are both TRUE). */
{
if (distance.infinite != 0) {
if (Is_Zero(distance.finite)) {
/* the distance has an infinite component, but no finite component */
if (distance.infinite == 1)
if (centre)
fprintf(stream, "\\multicolumn{1}{c%s}{$\\infty$}",
rule_at_right ? "|" : "");
else
fprintf(stream, "$\\infty$");
else if (centre)
fprintf(stream, "\\multicolumn{1}{c%s}{$%u\\infty$}",
rule_at_right ? "|" : "", distance.infinite);
else
fprintf(stream, "$%u\\infty$", distance.infinite);
} else {
/* the distance has both a finite component and an infinite
component */
if (distance.infinite == 1) {
fprintf(stream, "$\\infty$+");
Write_Floating_Point(stream, distance.finite, Empty_String);
} else {
fprintf(stream, "$%u\\infty$+", distance.infinite);
Write_Floating_Point(stream, distance.finite, Empty_String);
}
}
} else {
if (Is_Zero(distance.finite)) {
/* the distance has neither a finite component nor an infinite
component */
if (centre)
fprintf(stream, "\\multicolumn{1}{c%s}{--}", rule_at_right ? "|" : "");
else
fprintf(stream, "--");
} else
/* the distance has a finite component, but no infinite component */
Write_Floating_Point(stream, distance.finite, Empty_String);
}
}
static void
write_metrics(
file stream,
metrics_type metrics,
boolean weighted_association_coefficient,
boolean correlation_coefficients)
/* Writes, as cells in a table of distances, each of the metrics in metrics:
the known distance, the unknown distance, the unweighted distance, the
association coefficient, the weighted association coefficient (if
weighted_association_coefficient is TRUE), the correlation coefficient (if
correlation_coefficients is TRUE), and the weighted correlation
coefficient (if correlation_coefficients is TRUE). */
{
write_distance(stream, metrics.distance.known, TRUE, FALSE);
fprintf(stream, "&");
write_distance(stream, metrics.distance.unknown, TRUE, TRUE);
fprintf(stream, "&");
if (metrics.number_of_known_pairs == 0) {
/* there are no known pairs */
fprintf(stream, "--&--&");
if (weighted_association_coefficient)
fprintf(stream, "--&");
if (correlation_coefficients)
fprintf(stream, "&&");
} else {
if (metrics.number_of_known_differences == 0) {
/* there are no known differences */
fprintf(stream, "--&--&");
if (weighted_association_coefficient)
fprintf(stream, "--&");
} else {
/* there are known differences */
fprintf(stream, "%u&", metrics.number_of_known_differences);
Write_Floating_Point(stream,
(floating_point) metrics.number_of_known_differences /
metrics.number_of_known_pairs, Empty_String);
fprintf(stream, "&");
if (weighted_association_coefficient) {
Write_Floating_Point(stream,
metrics.weighted_association_coefficient, Empty_String);
fprintf(stream, "&");
}
}
if (correlation_coefficients)
if (metrics.correlation_coefficient.meaningless)
/* either this case (or ideal point or centroid) or the instant
case has all attribute values equal: the correlation
coefficients are meaningless */
fprintf(stream, "&&");
else {
/* write values for the correlation coefficients */
Write_Floating_Point(stream,
metrics.correlation_coefficient.unweighted, Empty_String);
fprintf(stream, "&");
Write_Floating_Point(stream,
metrics.correlation_coefficient.weighted, Empty_String);
fprintf(stream, "&");
}
}
}
static boolean
all_three_equal(
distance_subtype x,
distance_subtype y,
distance_subtype z)
/* Returns TRUE, iff distances x, y and z are equal. */
{
return ((x.infinite == y.infinite) &&
Is_Equal(x.finite, y.finite, Distance_Precision) &&
(x.infinite == z.infinite) &&
Is_Equal(x.finite, z.finite, Distance_Precision));
}
static void
write_result(
file stream,
cardinal count,
cardinal first_result_row,
boolean write_directions,
result *result_pointer)
/* Writes the identifier, and the strength of every non-zero direction (if
write_directions is TRUE), for the result pointed to by result_pointer, as
cells in a table of distances. Writes the identifier, then the
directions, in consecutive rows of the "Result" column, starting with row
first_result_row so that the information is centred vertically. */
{
static boolean specified_to_be_written,
ideal_point_to_be_written,
centroid_to_be_written,
all_to_be_written;
if (count == first_result_row) {
/* the result identifier should be written in this row */
fprintf(stream, "{%s %s}", Identifier_Font, result_pointer->identifier);
if (write_directions) {
/* determine which directions will be written (on subsequent
invocations of this function) */
specified_to_be_written =
!Is_Zero_Subdistance(result_pointer->specified_direction);
ideal_point_to_be_written =
!Is_Zero_Subdistance(result_pointer->ideal_point_direction);
centroid_to_be_written =
!Is_Zero_Subdistance(result_pointer->centroid_direction);
all_to_be_written = (specified_to_be_written &&
ideal_point_to_be_written && centroid_to_be_written &&
all_three_equal(result_pointer->specified_direction,
result_pointer->ideal_point_direction,
result_pointer->centroid_direction));
}
} else if (write_directions && (count > first_result_row)) {
/* write the strength of the next non-zero direction */
if (all_to_be_written) {
fprintf(stream, "%s\\,", All_Directions_Symbol);
write_distance(stream, result_pointer->specified_direction, FALSE, FALSE);
all_to_be_written = FALSE;
specified_to_be_written = FALSE;
ideal_point_to_be_written = FALSE;
centroid_to_be_written = FALSE;
} else if (specified_to_be_written) {
fprintf(stream, "%s\\,", Specified_Direction_Symbol);
write_distance(stream, result_pointer->specified_direction, FALSE, FALSE);
specified_to_be_written = FALSE;
} else if (ideal_point_to_be_written) {
fprintf(stream, "%s\\,", Ideal_Point_Direction_Symbol);
write_distance(stream, result_pointer->ideal_point_direction, FALSE, FALSE);
ideal_point_to_be_written = FALSE;
} else if (centroid_to_be_written) {
fprintf(stream, "%s\\,", Centroid_Direction_Symbol);
write_distance(stream, result_pointer->centroid_direction, FALSE, FALSE);
centroid_to_be_written = FALSE;
}
}
}
extern void
Write_Matrix(
file stream,
area *area_pointer,
vector_element *facts_head,
court *court_head,
boolean hypothetical,
cardinal number)
/* Writes a matrix of attribute values and (if facts_head is TRUE) metric
information, for the instant case, the cases in the area pointed to by
area_pointer, the ideal points in that area, and each result's centroid
(if they have been calculated). If number is not zero then the instant
case is actually a hypothetical (if hypothetical is TRUE) or an
instantiation, and number is its number. */
{
result *result_pointer;
kase *case_pointer;
matrix_element *matrix_pointer;
vector_element *vector_pointer;
centroid_element *centroid_pointer;
cardinal count,
first_result_row;
Indent(stream, 1);
fprintf(stream, "\\begin{small}\n");
Indent(stream, 2);
fprintf(stream, "\\begin{tabular}{*{2}{|c}");
if (area_pointer->number_of_attributes > 1)
fprintf(stream, "*{%u}{@{\\hspace{%s}}c}|",
area_pointer->number_of_attributes - 1, Matrix_Column_Separation);
if (court_head != NULL)
/* there will be a column for the rank of each case's court */
fprintf(stream, "r|");
if (facts_head != NULL) {
/* there will be columns for metric information */
fprintf(stream, "r@{\\hspace{%s}}r|r|", Column_Separation);
if (area_pointer->infinite_weight)
/* at least one of the attribute's weights is infinite, so the
values obtained for S' are meaningless: there will be no S'
column */
fprintf(stream, "c|");
else
/* there will be an S' column */
fprintf(stream, "c@{\\hspace{%s}}c|", Column_Separation);
if (area_pointer->correlation_coefficients)
/* the instant case does not have all attribute values the same, and
not every case, ideal point and centroid has all attribute values
the same: there will be columns for the correlation coefficients
r and r' (if either of these conditions does not hold, all the
values of r and r' are meaningless) */
fprintf(stream, "r@{\\hspace{%s}}r|", Column_Separation);
}
fprintf(stream, "c|}\\hline\n");
/* write the column headings */
Indent(stream, 3);
fprintf(stream, "&\\multicolumn{%u}{|c|}{\\it Attributes\\/}&",
area_pointer->number_of_attributes);
if (court_head != NULL)
fprintf(stream, "&");
if (facts_head != NULL) {
fprintf(stream, "&&&&");
if (!area_pointer->infinite_weight)
fprintf(stream, "&");
if (area_pointer->correlation_coefficients)
fprintf(stream, "&&");
}
fprintf(stream, "\\\\\n");
Indent(stream, 3);
fprintf(stream, "\\smash{\\raisebox{%s}{\\it Case\\/}}&", Raise_Height);
for (count = 1; count <= area_pointer->number_of_attributes; count++)
fprintf(stream, "$A_{%u}$&", count);
if (court_head != NULL)
fprintf(stream, "\\multicolumn{1}{c|}{\\smash{\\raisebox{%s}{$c$}}}&",
Raise_Height);
if (facts_head != NULL) {
fprintf(stream,
"\\multicolumn{1}{c}{\\smash{\\raisebox{%s}{$d_{\\rm K}$}}}&"
"\\multicolumn{1}{c|}{\\smash{\\raisebox{%s}{$d_{\\rm U}$}}}&"
"\\multicolumn{1}{c|}{\\smash{\\raisebox{%s}{$\\Delta$}}}&"
"\\smash{\\raisebox{%s}{$S$}}&",
Raise_Height, Raise_Height, Raise_Height, Raise_Height);
if (!area_pointer->infinite_weight)
fprintf(stream, "\\smash{\\raisebox{%s}{$S'$}}&",
Raise_Height);
if (area_pointer->correlation_coefficients)
fprintf(stream, "\\multicolumn{1}{c}{\\smash{\\raisebox{%s}{$r$}}}&"
"\\multicolumn{1}{c|}{\\smash{\\raisebox{%s}{$r'$}}}&",
Raise_Height, Raise_Height);
}
fprintf(stream, "\\smash{\\raisebox{%s}{\\it Result\\/}}\\\\\\hline",
Raise_Height);
if (facts_head != NULL) {
/* write details of the instant case */
fprintf(stream, "\\hline\n");
Indent(stream, 3);
if (number == 0)
/* the instant case is the uninstantiated and unhypothesized instant
case */
fprintf(stream, "$C_{\\rm Instant}$&");
else if (hypothetical)
/* the instant case is hypothetical number */
fprintf(stream, "$C_{\\mbox{\\scriptsize Hypo-%u}}$&", number);
else
/* the instant case is instantiation number */
fprintf(stream, "$C_{\\mbox{\\scriptsize Inst-%u}}$&", number);
/* write the attribute values for the instant case */
for (vector_pointer = facts_head; vector_pointer != NULL;
vector_pointer = vector_pointer->next)
fprintf(stream, "%s&",
vector_pointer->attribute_value == YES ? Yes_Symbol :
vector_pointer->attribute_value == NO ? No_Symbol :
Unknown_Symbol);
/* leave an appropriate number of columns empty */
fprintf(stream, "\\multicolumn{%u}{c|}{}\\\\\\hline",
court_head == NULL ?
area_pointer->infinite_weight ?
area_pointer->correlation_coefficients ? 7 : 5 :
area_pointer->correlation_coefficients ? 8 : 6 :
area_pointer->infinite_weight ?
area_pointer->correlation_coefficients ? 8 : 6 :
area_pointer->correlation_coefficients ? 9 : 7);
}
/* for every result ... */
for (result_pointer = area_pointer->result_head; result_pointer != NULL;
result_pointer = result_pointer->next) {
/* determine the first row in which information should appear, for this
result, in the "Result" column so that the information is centred
vertically */
first_result_row = 0;
for (case_pointer = result_pointer->case_head; case_pointer != NULL;
case_pointer = case_pointer->next)
first_result_row++;
if (result_pointer->ideal_point_head != NULL)
first_result_row++;
if (result_pointer->centroid_head != NULL)
first_result_row++;
if (first_result_row != 0) {
if ((facts_head != NULL) && (first_result_row > 1) &&
!Is_Zero_Subdistance(result_pointer->specified_direction)) {
first_result_row--;
if (!all_three_equal(result_pointer->specified_direction,
result_pointer->ideal_point_direction,
result_pointer->centroid_direction)) {
if ((first_result_row > 1) &&
!Is_Zero_Subdistance(result_pointer->ideal_point_direction))
first_result_row--;
if ((first_result_row > 1) &&
!Is_Zero_Subdistance(result_pointer->centroid_direction))
first_result_row--;
}
}
first_result_row = (first_result_row + 1) / 2;
count = 1;
fprintf(stream, "\\hline");
/* for every case with this result ... */
for (case_pointer = result_pointer->case_head; case_pointer != NULL;
case_pointer = case_pointer->next) {
fprintf(stream, "\n");
Indent(stream, 3);
fprintf(stream, "$C_{%u}$&", case_pointer->number);
/* write the attribute values for this case */
for (matrix_pointer = case_pointer->matrix_head; matrix_pointer != NULL;
matrix_pointer = matrix_pointer->case_next)
fprintf(stream, "%s&",
matrix_pointer->attribute_value == YES ? Yes_Symbol :
matrix_pointer->attribute_value == NO ? No_Symbol :
Unknown_Symbol);
if (court_head != NULL)
/* write the rank of the case's court */
if ((case_pointer->court_string != NULL) &&
(case_pointer->court_rank != 0))
fprintf(stream, "%u&", case_pointer->court_rank);
else
fprintf(stream, "\\footnotesize?&");
if (facts_head != NULL)
write_metrics(stream, case_pointer->metrics,
!area_pointer->infinite_weight, area_pointer->correlation_coefficients);
write_result(stream, count++, first_result_row, facts_head != NULL,
result_pointer);
fprintf(stream, "\\\\");
}
/* write a line (an appropriate number of columns wide) under the
cases for this result */
if ((result_pointer->case_head != NULL) &&
((result_pointer->ideal_point_head != NULL) ||
(result_pointer->centroid_head != NULL)))
fprintf(stream, "\\cline{2-%u}", facts_head == NULL ?
court_head == NULL ?
area_pointer->number_of_attributes + 1 :
area_pointer->number_of_attributes + 2 :
court_head == NULL ?
area_pointer->infinite_weight ?
area_pointer->correlation_coefficients ?
area_pointer->number_of_attributes + 7 :
area_pointer->number_of_attributes + 5 :
area_pointer->correlation_coefficients ?
area_pointer->number_of_attributes + 8 :
area_pointer->number_of_attributes + 6 :
area_pointer->infinite_weight ?
area_pointer->correlation_coefficients ?
area_pointer->number_of_attributes + 8 :
area_pointer->number_of_attributes + 6 :
area_pointer->correlation_coefficients ?
area_pointer->number_of_attributes + 9 :
area_pointer->number_of_attributes + 7);
if (result_pointer->ideal_point_head != NULL) {
/* this result has an ideal point, so write its details */
fprintf(stream, "\n");
Indent(stream, 3);
fprintf(stream, "$I_{\\mbox{\\scriptsize%s %s}}$&",
Identifier_Font, result_pointer->identifier);
/* write the attribute values for this ideal point */
for (vector_pointer = result_pointer->ideal_point_head;
vector_pointer != NULL; vector_pointer = vector_pointer->next)
fprintf(stream, "%s&", (vector_pointer->attribute_value == YES ?
Yes_Symbol : (vector_pointer->attribute_value == NO ?
No_Symbol : Unknown_Symbol)));
if (court_head != NULL)
fprintf(stream, "&");
if (facts_head != NULL)
write_metrics(stream, result_pointer->ideal_point_metrics,
!area_pointer->infinite_weight, area_pointer->correlation_coefficients);
write_result(stream, count++, first_result_row, facts_head != NULL,
result_pointer);
fprintf(stream, "\\\\");
}
if (result_pointer->centroid_head != NULL) {
/* this result has a centroid, so write its details */
fprintf(stream, "\n");
Indent(stream, 3);
fprintf(stream, "$\\mu_{\\mbox{\\scriptsize%s %s}}$&",
Identifier_Font, result_pointer->identifier);
/* write the attribute values for this centroid */
for (centroid_pointer = result_pointer->centroid_head;
centroid_pointer != NULL; centroid_pointer = centroid_pointer->next)
fprintf(stream, "%s&",
centroid_pointer->unknown ? Unknown_Symbol :
Nearest_Attribute_Value(centroid_pointer->value) == YES ?
Yes_Symbol : No_Symbol);
if (court_head != NULL)
fprintf(stream, "&");
if (facts_head != NULL)
write_metrics(stream, result_pointer->centroid_metrics,
!area_pointer->infinite_weight, area_pointer->correlation_coefficients);
write_result(stream, count++, first_result_row, facts_head != NULL,
result_pointer);
fprintf(stream, "\\\\");
}
fprintf(stream, "\\hline");
}
}
fprintf(stream, "\n");
Indent(stream, 2);
fprintf(stream, "\\end{tabular}\n");
Indent(stream, 1);
fprintf(stream, "\\end{small}\n\n");
}
static void
write_opening_and_closing(
file dump_stream,
area *area_pointer,
boolean verbose)
/* Writes the opening and closing strings for the area pointed to by
area_pointer. Writes each string in full only if verbose is TRUE. */
{
if (area_pointer->opening != NULL) {
fprintf(dump_stream, "%s{Opening}\n\n", Subheading);
Indent(dump_stream, 1);
fprintf(dump_stream, "\\begin{list}{}{\\leftmargin=0mm}\\item[]\n");
if (verbose)
Write(dump_stream, area_pointer->opening, Empty_String, 2, Hang);
else
Write(dump_stream, "[Opening.]", Empty_String, 2, Hang);
Indent(dump_stream, 1);
fprintf(dump_stream, "\\end{list}\n\n");
}
if (area_pointer->closing != NULL) {
fprintf(dump_stream, "%s{Closing}\n\n", Subheading);
Indent(dump_stream, 1);
fprintf(dump_stream, "\\begin{list}{}{\\leftmargin=0mm}\\item[]\n");
if (verbose)
Write(dump_stream, area_pointer->closing, Empty_String, 2, Hang);
else
Write(dump_stream, "[Closing.]", Empty_String, 2, Hang);
Indent(dump_stream, 1);
fprintf(dump_stream, "\\end{list}\n\n");
}
}
static void
write_result_list(
file dump_stream,
result *result_pointer)
/* Writes details of each result in the list of results pointed to by
result_pointer. */
{
fprintf(dump_stream, "%s{Results}\n\n", Subheading);
Indent(dump_stream, 1);
fprintf(dump_stream, "\\begin{description}\n\n");
/* while there are still results ... */
while (result_pointer != NULL) {
Indent(dump_stream, 2);
fprintf(dump_stream, "\\item[\\rm{%s %s}:]\n",
Identifier_Font, result_pointer->identifier);
Write(dump_stream, result_pointer->string, ".\n", 3, No_Hang);
result_pointer = result_pointer->next;
}
Indent(dump_stream, 1);
fprintf(dump_stream, "\\end{description}\n\n");
}
static void
write_attribute_list(
file dump_stream,
attribute *attribute_pointer)
/* Writes details of each attribute in the list of attributes pointed to by
attribute_pointer. */
{
direction_list_element *direction_list_pointer;
identifier_list_element *identifier_list_pointer;
fprintf(dump_stream, "%s{Attributes}\n\n", Subheading);
Indent(dump_stream, 1);
fprintf(dump_stream, "\\begin{description}\n\n");
/* while there are still attributes ... */
while (attribute_pointer != NULL) {
Indent(dump_stream, 2);
fprintf(dump_stream, "\\item[\\rm$A_{%u}$:]\n", attribute_pointer->number);
if (attribute_pointer->external_attribute) {
/* the attribute is external, so indicate the area to which it is
linked */
Indent(dump_stream, 3);
fprintf(dump_stream, "%s {%s %s} area\n", External_Area_Symbol,
Identifier_Font, attribute_pointer->details.external.area_identifier);
} else
/* the attribute is local, so write the attribute's question */
Write(dump_stream, attribute_pointer->details.local.question, "?", 3, No_Hang);
fprintf(dump_stream, "\n");
Indent(dump_stream, 3);
fprintf(dump_stream, "\\begin{description}\n\n");
if (attribute_pointer->yes != NULL) {
/* the attribute has a YES string, so write it */
Indent(dump_stream, 4);
fprintf(dump_stream, "\\item[\\sc yes:]\n");
Write(dump_stream, attribute_pointer->yes, ".\n", 5, No_Hang);
if (attribute_pointer->external_attribute) {
/* the attribute is external, so indicate the association of
results from the external area with YES values of this
attribute */
identifier_list_pointer = attribute_pointer->details.external.yes_identifier_head;
while (identifier_list_pointer != NULL) {
if (identifier_list_pointer ==
attribute_pointer->details.external.yes_identifier_head) {
/* this is the first identifier to write */
Indent(dump_stream, 5);
fprintf(dump_stream, "%s {%s %s}", External_Result_Symbol,
Identifier_Font, identifier_list_pointer->identifier);
} else {
fprintf(dump_stream, "~%s\n", Disjunction_Symbol);
Indent(dump_stream, 5);
fprintf(dump_stream, "{%s %s}", Identifier_Font,
identifier_list_pointer->identifier);
}
identifier_list_pointer = identifier_list_pointer->next;
}
if (attribute_pointer->details.external.yes_identifier_head != NULL)
fprintf(dump_stream, "\n\n");
}
/* indicate the specified direction for YES values of this attribute */
direction_list_pointer = attribute_pointer->yes_direction_head;
while (direction_list_pointer != NULL) {
if (direction_list_pointer == attribute_pointer->yes_direction_head) {
/* this is the first identifier to write */
Indent(dump_stream, 5);
fprintf(dump_stream, "%s {%s %s}", Specified_Direction_Symbol,
Identifier_Font, direction_list_pointer->result->identifier);
} else {
fprintf(dump_stream, "~%s\n", Disjunction_Symbol);
Indent(dump_stream, 5);
fprintf(dump_stream, "{%s %s}", Identifier_Font,
direction_list_pointer->result->identifier);
}
direction_list_pointer = direction_list_pointer->next;
}
if (attribute_pointer->yes_direction_head != NULL)
fprintf(dump_stream, "\n\n");
}
if (attribute_pointer->no != NULL) {
/* the attribute has a NO string, so write it */
Indent(dump_stream, 4);
fprintf(dump_stream, "\\item[\\sc no:]\n");
Write(dump_stream, attribute_pointer->no, ".\n", 5, No_Hang);
if (attribute_pointer->external_attribute) {
/* the attribute is external, so indicate the association of
results from the external area with NO values of this
attribute */
identifier_list_pointer = attribute_pointer->details.external.no_identifier_head;
while (identifier_list_pointer != NULL) {
if (identifier_list_pointer ==
attribute_pointer->details.external.no_identifier_head) {
/* this is the first identifier to write */
Indent(dump_stream, 5);
fprintf(dump_stream, "%s {%s %s}", External_Result_Symbol,
Identifier_Font, identifier_list_pointer->identifier);
} else {
fprintf(dump_stream, "~%s\n", Disjunction_Symbol);
Indent(dump_stream, 5);
fprintf(dump_stream, "{%s %s}", Identifier_Font,
identifier_list_pointer->identifier);
}
identifier_list_pointer = identifier_list_pointer->next;
}
if (attribute_pointer->details.external.no_identifier_head != NULL)
fprintf(dump_stream, "\n\n");
}
/* indicate the specified direction for NO values of this attribute */
direction_list_pointer = attribute_pointer->no_direction_head;
while (direction_list_pointer != NULL) {
if (direction_list_pointer == attribute_pointer->no_direction_head) {
/* this is the first identifier to write */
Indent(dump_stream, 5);
fprintf(dump_stream, "%s {%s %s}", Specified_Direction_Symbol,
Identifier_Font, direction_list_pointer->result->identifier);
} else {
fprintf(dump_stream, "~%s\n", Disjunction_Symbol);
Indent(dump_stream, 5);
fprintf(dump_stream, "{%s %s}", Identifier_Font,
direction_list_pointer->result->identifier);
}
direction_list_pointer = direction_list_pointer->next;
}
if (attribute_pointer->no_direction_head != NULL)
fprintf(dump_stream, "\n\n");
}
if (attribute_pointer->unknown != NULL) {
/* the attribute has an UNKNOWN string, so write it */
Indent(dump_stream, 4);
fprintf(dump_stream, "\\item[\\sc unknown:]\n");
Write(dump_stream, attribute_pointer->unknown, ".\n", 5, No_Hang);
if (attribute_pointer->external_attribute) {
/* the attribute is external, so indicate the association of
results from the external area with UNKNOWN values of this
attribute */
identifier_list_pointer =
attribute_pointer->details.external.unknown_identifier_head;
while (identifier_list_pointer != NULL) {
if (identifier_list_pointer ==
attribute_pointer->details.external.unknown_identifier_head) {
/* this is the first identifier to write */
Indent(dump_stream, 5);
fprintf(dump_stream, "%s {%s %s}", External_Result_Symbol,
Identifier_Font, identifier_list_pointer->identifier);
} else {
fprintf(dump_stream, "~%s\n", Disjunction_Symbol);
Indent(dump_stream, 5);
fprintf(dump_stream, "{%s %s}", Identifier_Font,
identifier_list_pointer->identifier);
}
identifier_list_pointer = identifier_list_pointer->next;
}
if (attribute_pointer->details.external.unknown_identifier_head != NULL)
fprintf(dump_stream, "\n\n");
}
/* indicate the specified direction for UNKNOWN values of this
attribute */
direction_list_pointer = attribute_pointer->unknown_direction_head;
while (direction_list_pointer != NULL) {
if (direction_list_pointer == attribute_pointer->unknown_direction_head) {
/* this is the first identifier to write */
Indent(dump_stream, 5);
fprintf(dump_stream, "%s {%s %s}", Specified_Direction_Symbol,
Identifier_Font, direction_list_pointer->result->identifier);
} else {
fprintf(dump_stream, "~%s\n", Disjunction_Symbol);
Indent(dump_stream, 5);
fprintf(dump_stream, "{%s %s}", Identifier_Font,
direction_list_pointer->result->identifier);
}
direction_list_pointer = direction_list_pointer->next;
}
if (attribute_pointer->unknown_direction_head != NULL)
fprintf(dump_stream, "\n\n");
}
Indent(dump_stream, 3);
fprintf(dump_stream, "\\end{description}\n\n");
if (!attribute_pointer->external_attribute &&
(attribute_pointer->details.local.help != NULL))
/* the attribute has a help string, so write it */
Write(dump_stream, attribute_pointer->details.local.help, "\n", 3, No_Hang);
attribute_pointer = attribute_pointer->next;
}
Indent(dump_stream, 1);
fprintf(dump_stream, "\\end{description}\n\n");
}
extern void
Write_Year_and_Court(
file stream,
kase *case_pointer,
cardinal level)
/* Describes the case pointed to by case_pointer as "a year decision of
court". */
{
cardinal hundreds = case_pointer->year / 100;
Indent(stream, level);
if ((hundreds == 8) || (hundreds == 11) || (hundreds == 18))
fprintf(stream, "an");
else
fprintf(stream, "a");
fprintf(stream, " %u decision", case_pointer->year);
if (case_pointer->court_string != NULL) {
fprintf(stream, " of\n");
Indent(stream, level);
fprintf(stream, " %s", case_pointer->court_string);
}
}
static void
write_case_list(
file dump_stream,
file log_stream,
area *area_pointer,
boolean verbose)
/* Writes details of each case in the area pointed to by area_pointer.
Summarizes each case in full only if verbose is TRUE. */
{
result *result_pointer = area_pointer->result_head;
kase *case_pointer;
attribute *attribute_pointer;
matrix_element *matrix_pointer;
vector_element *vector_pointer;
string attribute_string;
char message[Max_Error_Message_Length];
/* while there are still results ... */
while (result_pointer != NULL) {
if ((result_pointer->case_head != NULL) ||
(result_pointer->ideal_point_head != NULL)) {
/* this result has a case or an ideal point */
fprintf(dump_stream, "%s{Cases in which %s}\n\n", Subheading,
result_pointer->string);
Indent(dump_stream, 1);
fprintf(dump_stream, "\\begin{description}\n\n", result_pointer->string);
/* for every case with this result ... */
for (case_pointer = result_pointer->case_head; case_pointer != NULL;
case_pointer = case_pointer->next) {
Indent(dump_stream, 2);
fprintf(dump_stream,
"\\item[\\rm$C_{%u}$:]\\frenchspacing\n", case_pointer->number);
Indent(dump_stream, 3);
fprintf(dump_stream,
"{\\it %s\\/} \\nonfrenchspacing\n", case_pointer->name);
Indent(dump_stream, 3);
fprintf(dump_stream, "%s\n", case_pointer->citation);
if (case_pointer->short_name != case_pointer->name) {
Indent(dump_stream, 3);
fprintf(dump_stream, "(``\\frenchspacing\n");
Indent(dump_stream, 3);
fprintf(dump_stream, "{\\it %s\\/}\\nonfrenchspacing'')\n",
case_pointer->short_name);
}
fprintf(dump_stream, "\n");
attribute_pointer = area_pointer->attribute_head;
matrix_pointer = case_pointer->matrix_head;
Indent(dump_stream, 3);
fprintf(dump_stream, "\\begin{description}\n\n");
/* while there are still attributes ... */
while (attribute_pointer != NULL) {
/* write the strings corresponding to each attribute value for
the case */
attribute_string = matrix_pointer->attribute_value == YES ?
attribute_pointer->yes : matrix_pointer->attribute_value == NO ?
attribute_pointer->no : attribute_pointer->unknown;
Indent(dump_stream, 4);
fprintf(dump_stream, "\\item[\\rm$A_{%u}$:]\n",
attribute_pointer->number);
if (attribute_string == NULL) {
sprintf(message,
"A%u in C%u in %s area has a value "
"for which there is no string",
attribute_pointer->number, case_pointer->number,
area_pointer->identifier);
warning(log_stream, message);
Indent(dump_stream, 5);
fprintf(dump_stream, "%s\n", Null_String);
} else
Write(dump_stream, attribute_string, ".", 5, No_Hang);
fprintf(dump_stream, "\n");
matrix_pointer = matrix_pointer->case_next;
attribute_pointer = attribute_pointer->next;
}
/* summarize the case */
Indent(dump_stream, 3);
fprintf(dump_stream, "\\end{description}\n\n");
if (case_pointer->summary != NULL) {
Indent(dump_stream, 3);
fprintf(dump_stream, "In \\frenchspacing\n");
Indent(dump_stream, 3);
fprintf(dump_stream, "{\\it %s}\\nonfrenchspacing,%%\n",
case_pointer->name);
Indent(dump_stream, 3);
fprintf(dump_stream, "\\footnote{%s.}\n", case_pointer->citation);
if (verbose) {
Write_Year_and_Court(dump_stream, case_pointer, 3);
fprintf(dump_stream, ",\n");
if (case_pointer->summary != NULL)
Write(dump_stream, case_pointer->summary, Empty_String, 3, Hang);
} else
Write(dump_stream, "[summary].\n", Empty_String, 3, Hang);
fprintf(dump_stream, "\n");
}
}
if (result_pointer->ideal_point_head != NULL) {
/* this result has an ideal point, so write its details */
Indent(dump_stream, 2);
fprintf(dump_stream, "\\item[$I_{\\mbox{\\scriptsize%s %s}}$]\n",
Identifier_Font, result_pointer->identifier);
Indent(dump_stream, 3);
fprintf(dump_stream, "(the ideal case in which\n");
Indent(dump_stream, 3);
fprintf(dump_stream, "%s):\n\n", result_pointer->string);
attribute_pointer = area_pointer->attribute_head;
vector_pointer = result_pointer->ideal_point_head;
Indent(dump_stream, 3);
fprintf(dump_stream, "\\begin{description}\n\n");
/* while there are still attributes ... */
while (attribute_pointer != NULL) {
/* write the strings corresponding to each attribute value for
the ideal point */
attribute_string = vector_pointer->attribute_value == YES ?
attribute_pointer->yes : vector_pointer->attribute_value == NO ?
attribute_pointer->no : attribute_pointer->unknown;
Indent(dump_stream, 4);
fprintf(dump_stream, "\\item[\\rm$A_{%u}$:]\n",
attribute_pointer->number);
if (attribute_string == NULL) {
sprintf(message,
"A%u in ideal point %s in %s area has a value "
"for which there is no string",
attribute_pointer->number, result_pointer->identifier,
area_pointer->identifier);
warning(log_stream, message);
Indent(dump_stream, 5);
fprintf(dump_stream, "%s\n", Null_String);
} else
Write(dump_stream, attribute_string, ".", 5, No_Hang);
fprintf(dump_stream, "\n");
vector_pointer = vector_pointer->next;
attribute_pointer = attribute_pointer->next;
}
Indent(dump_stream, 3);
fprintf(dump_stream, "\\end{description}\n\n");
}
Indent(dump_stream, 1);
fprintf(dump_stream, "\\end{description}\n\n");
}
result_pointer = result_pointer->next;
}
}
extern void
Dump_Specification(
file dump_stream,
file log_stream,
case_law_specification case_law,
boolean inputable_latex,
boolean verbose)
/* Writes to dump_stream a formatted version of the specification case_law.
Writes LaTeX code that can be included in another LaTeX document (i.e. not
stand-alone code), if inputable_latex is TRUE. Summarizes cases in full,
and writes opening and closing strings in full, if verbose is TRUE. */
{
area *area_pointer;
fprintf(dump_stream, "%% Dump file\n\n");
Write_LaTeX_Header(dump_stream, inputable_latex);
if (case_law.court_head != NULL)
write_hierarchy_table(dump_stream, case_law.court_head);
/* for every area ... */
for (area_pointer = case_law.area_head; area_pointer != NULL;
area_pointer = area_pointer->next) {
fprintf(dump_stream, "%s{%s area}\n\n", Heading,
area_pointer->identifier);
Write_Matrix(dump_stream, area_pointer, NULL, case_law.court_head, FALSE, 0);
write_opening_and_closing(dump_stream, area_pointer, verbose);
write_result_list(dump_stream, area_pointer->result_head);
write_attribute_list(dump_stream, area_pointer->attribute_head);
write_case_list(dump_stream, log_stream, area_pointer, verbose);
}
Write_LaTeX_Trailer(dump_stream, inputable_latex);
}
Other SHYSTER modules: Shyster, Statutes, Cases, Tokenizer, Parser, Checker, Scales, Adjuster, Consultant, Odometer and Reporter.