From 80cd6f57d8009a3c7b4ca67566fb6e4da1448fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20=C3=96zkural?= Date: Thu, 21 Jul 2005 00:28:17 +0000 Subject: [PATCH] * latex'e cevir, guzellestir ortami * review'a graph theory'le ilgili bir paragraf yaz. --- doc/algorithm.sty | 79 ++++++++++++++++++ doc/algorithmic.sty | 158 +++++++++++++++++++++++++++++++++++ doc/dependency.pdf | Bin 0 -> 67210 bytes doc/dependency.tex | 197 ++++++++++++++++++++++++++++++++++++++++++++ doc/dependency.txt | 141 ------------------------------- doc/prettyref.sty | 37 +++++++++ 6 files changed, 471 insertions(+), 141 deletions(-) create mode 100644 doc/algorithm.sty create mode 100644 doc/algorithmic.sty create mode 100644 doc/dependency.pdf create mode 100644 doc/dependency.tex delete mode 100644 doc/dependency.txt create mode 100644 doc/prettyref.sty diff --git a/doc/algorithm.sty b/doc/algorithm.sty new file mode 100644 index 00000000..843e3d5b --- /dev/null +++ b/doc/algorithm.sty @@ -0,0 +1,79 @@ +% ALGORITHM STYLE -- Released 8 April 1996 +% for LaTeX-2e +% Copyright -- 1994 Peter Williams +% E-mail Peter.Williams@dsto.defence.gov.au +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{algorithm} +\typeout{Document Style `algorithm' - floating environment} + +\RequirePackage{float} +\RequirePackage{ifthen} +\newcommand{\ALG@within}{nothing} +\newboolean{ALG@within} +\setboolean{ALG@within}{false} +\newcommand{\ALG@floatstyle}{ruled} +\newcommand{\ALG@name}{Algorithm} +\newcommand{\listalgorithmname}{List of \ALG@name s} + +% Declare Options +% first appearance +\DeclareOption{plain}{ + \renewcommand{\ALG@floatstyle}{plain} +} +\DeclareOption{ruled}{ + \renewcommand{\ALG@floatstyle}{ruled} +} +\DeclareOption{boxed}{ + \renewcommand{\ALG@floatstyle}{boxed} +} +% then numbering convention +\DeclareOption{part}{ + \renewcommand{\ALG@within}{part} + \setboolean{ALG@within}{true} +} +\DeclareOption{chapter}{ + \renewcommand{\ALG@within}{chapter} + \setboolean{ALG@within}{true} +} +\DeclareOption{section}{ + \renewcommand{\ALG@within}{section} + \setboolean{ALG@within}{true} +} +\DeclareOption{subsection}{ + \renewcommand{\ALG@within}{subsection} + \setboolean{ALG@within}{true} +} +\DeclareOption{subsubsection}{ + \renewcommand{\ALG@within}{subsubsection} + \setboolean{ALG@within}{true} +} +\DeclareOption{nothing}{ + \renewcommand{\ALG@within}{nothing} + \setboolean{ALG@within}{true} +} +\DeclareOption*{\edef\ALG@name{\CurrentOption}} + +% ALGORITHM +% +\ProcessOptions +\floatstyle{\ALG@floatstyle} +\ifthenelse{\boolean{ALG@within}}{ + \ifthenelse{\equal{\ALG@within}{part}} + {\newfloat{algorithm}{htbp}{loa}[part]}{} + \ifthenelse{\equal{\ALG@within}{chapter}} + {\newfloat{algorithm}{htbp}{loa}[chapter]}{} + \ifthenelse{\equal{\ALG@within}{section}} + {\newfloat{algorithm}{htbp}{loa}[section]}{} + \ifthenelse{\equal{\ALG@within}{subsection}} + {\newfloat{algorithm}{htbp}{loa}[subsection]}{} + \ifthenelse{\equal{\ALG@within}{subsubsection}} + {\newfloat{algorithm}{htbp}{loa}[subsubsection]}{} + \ifthenelse{\equal{\ALG@within}{nothing}} + {\newfloat{algorithm}{htbp}{loa}}{} +}{ + \newfloat{algorithm}{htbp}{loa} +} +\floatname{algorithm}{\ALG@name} + +\newcommand{\listofalgorithms}{\listof{algorithm}{\listalgorithmname}} + diff --git a/doc/algorithmic.sty b/doc/algorithmic.sty new file mode 100644 index 00000000..68f18aa0 --- /dev/null +++ b/doc/algorithmic.sty @@ -0,0 +1,158 @@ +% ALGORITHMIC STYLE -- Released 8 APRIL 1996 +% for LaTeX version 2e +% Copyright -- 1994 Peter Williams +% E-mail PeterWilliams@dsto.defence.gov.au +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{algorithmic} +\typeout{Document Style `algorithmic' - environment} +% +\RequirePackage{ifthen} +\RequirePackage{calc} +\newboolean{ALC@noend} +\setboolean{ALC@noend}{false} +\newcounter{ALC@line} +\newcounter{ALC@rem} +\newlength{\ALC@tlm} +% +\DeclareOption{noend}{\setboolean{ALC@noend}{true}} +% +\ProcessOptions +% +% ALGORITHMIC +\newcommand{\algorithmicrequire}{\textbf{Require:}} +\newcommand{\algorithmicensure}{\textbf{Ensure:}} +\newcommand{\algorithmiccomment}[1]{\{#1\}} +\newcommand{\algorithmicend}{\textbf{end}} +\newcommand{\algorithmicif}{\textbf{if}} +\newcommand{\algorithmicthen}{\textbf{then}} +\newcommand{\algorithmicelse}{\textbf{else}} +\newcommand{\algorithmicelsif}{\algorithmicelse\ \algorithmicif} +\newcommand{\algorithmicendif}{\algorithmicend\ \algorithmicif} +\newcommand{\algorithmicfor}{\textbf{for}} +\newcommand{\algorithmicforall}{\textbf{for all}} +\newcommand{\algorithmicdo}{\textbf{do}} +\newcommand{\algorithmicendfor}{\algorithmicend\ \algorithmicfor} +\newcommand{\algorithmicwhile}{\textbf{while}} +\newcommand{\algorithmicendwhile}{\algorithmicend\ \algorithmicwhile} +\newcommand{\algorithmicloop}{\textbf{loop}} +\newcommand{\algorithmicendloop}{\algorithmicend\ \algorithmicloop} +\newcommand{\algorithmicrepeat}{\textbf{repeat}} +\newcommand{\algorithmicuntil}{\textbf{until}} +\def\ALC@item[#1]{% +\if@noparitem \@donoparitem + \else \if@inlabel \indent \par \fi + \ifhmode \unskip\unskip \par \fi + \if@newlist \if@nobreak \@nbitem \else + \addpenalty\@beginparpenalty + \addvspace\@topsep \addvspace{-\parskip}\fi + \else \addpenalty\@itempenalty \addvspace\itemsep + \fi + \global\@inlabeltrue +\fi +\everypar{\global\@minipagefalse\global\@newlistfalse + \if@inlabel\global\@inlabelfalse \hskip -\parindent \box\@labels + \penalty\z@ \fi + \everypar{}}\global\@nobreakfalse +\if@noitemarg \@noitemargfalse \if@nmbrlist \refstepcounter{\@listctr}\fi \fi +\sbox\@tempboxa{\makelabel{#1}}% +\global\setbox\@labels + \hbox{\unhbox\@labels \hskip \itemindent + \hskip -\labelwidth \hskip -\ALC@tlm + \ifdim \wd\@tempboxa >\labelwidth + \box\@tempboxa + \else \hbox to\labelwidth {\unhbox\@tempboxa}\fi + \hskip \ALC@tlm}\ignorespaces} +% +\newenvironment{algorithmic}[1][0]{ +\let\@item\ALC@item + \newcommand{\ALC@lno}{% +\ifthenelse{\equal{\arabic{ALC@rem}}{0}} +{{\footnotesize \arabic{ALC@line}:}}{}% +} +\let\@listii\@listi +\let\@listiii\@listi +\let\@listiv\@listi +\let\@listv\@listi +\let\@listvi\@listi +\let\@listvii\@listi + \newenvironment{ALC@g}{ + \begin{list}{\ALC@lno}{ \itemsep\z@ \itemindent\z@ + \listparindent\z@ \rightmargin\z@ + \topsep\z@ \partopsep\z@ \parskip\z@\parsep\z@ + \leftmargin 1em + \addtolength{\ALC@tlm}{\leftmargin} + } + } + {\end{list}} + \newcommand{\ALC@it}{\addtocounter{ALC@line}{1}\addtocounter{ALC@rem}{1}\ifthenelse{\equal{\arabic{ALC@rem}}{#1}}{\setcounter{ALC@rem}{0}}{}\item} + \newcommand{\ALC@com}[1]{\ifthenelse{\equal{##1}{default}}% +{}{\ \algorithmiccomment{##1}}} + \newcommand{\REQUIRE}{\item[\algorithmicrequire]} + \newcommand{\ENSURE}{\item[\algorithmicensure]} + \newcommand{\STATE}{\ALC@it} + \newcommand{\COMMENT}[1]{\algorithmiccomment{##1}} + \newenvironment{ALC@if}{\begin{ALC@g}}{\end{ALC@g}} + \newenvironment{ALC@for}{\begin{ALC@g}}{\end{ALC@g}} + \newenvironment{ALC@whl}{\begin{ALC@g}}{\end{ALC@g}} + \newenvironment{ALC@loop}{\begin{ALC@g}}{\end{ALC@g}} + \newenvironment{ALC@rpt}{\begin{ALC@g}}{\end{ALC@g}} + \renewcommand{\\}{\@centercr} + \newcommand{\IF}[2][default]{\ALC@it\algorithmicif\ ##2\ \algorithmicthen% +\ALC@com{##1}\begin{ALC@if}} + \newcommand{\ELSE}[1][default]{\end{ALC@if}\ALC@it\algorithmicelse% +\ALC@com{##1}\begin{ALC@if}} + \newcommand{\ELSIF}[2][default]% +{\end{ALC@if}\ALC@it\algorithmicelsif\ ##2\ \algorithmicthen% +\ALC@com{##1}\begin{ALC@if}} + \newcommand{\FOR}[2][default]{\ALC@it\algorithmicfor\ ##2\ \algorithmicdo% +\ALC@com{##1}\begin{ALC@for}} + \newcommand{\FORALL}[2][default]{\ALC@it\algorithmicforall\ ##2\ % +\algorithmicdo% +\ALC@com{##1}\begin{ALC@for}} + \newcommand{\WHILE}[2][default]{\ALC@it\algorithmicwhile\ ##2\ % +\algorithmicdo% +\ALC@com{##1}\begin{ALC@whl}} + \newcommand{\LOOP}[1][default]{\ALC@it\algorithmicloop% +\ALC@com{##1}\begin{ALC@loop}} + \newcommand{\REPEAT}[1][default]{\ALC@it\algorithmicrepeat% +\ALC@com{##1}\begin{ALC@rpt}} + \newcommand{\UNTIL}[1]{\end{ALC@rpt}\ALC@it\algorithmicuntil\ ##1} + \ifthenelse{\boolean{ALC@noend}}{ + \newcommand{\ENDIF}{\end{ALC@if}} + \newcommand{\ENDFOR}{\end{ALC@for}} + \newcommand{\ENDWHILE}{\end{ALC@whl}} + \newcommand{\ENDLOOP}{\end{ALC@loop}} + }{ + \newcommand{\ENDIF}{\end{ALC@if}\ALC@it\algorithmicendif} + \newcommand{\ENDFOR}{\end{ALC@for}\ALC@it\algorithmicendfor} + \newcommand{\ENDWHILE}{\end{ALC@whl}\ALC@it\algorithmicendwhile} + \newcommand{\ENDLOOP}{\end{ALC@loop}\ALC@it\algorithmicendloop} + } + \renewcommand{\@toodeep}{} + \begin{list}{\ALC@lno}{\setcounter{ALC@line}{0}\setcounter{ALC@rem}{0}% + \itemsep\z@ \itemindent\z@ \listparindent\z@% + \partopsep\z@ \parskip\z@ \parsep\z@% + \labelsep 0.5em \topsep 0.2em% +\ifthenelse{\equal{#1}{0}} + {\labelwidth 0.5em } + {\labelwidth 1.2em } +\leftmargin\labelwidth \addtolength{\leftmargin}{\labelsep} + \ALC@tlm\labelsep + } +} +{\end{list}} + + + + + + + + + + + + + + + diff --git a/doc/dependency.pdf b/doc/dependency.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0519862e2f5f15c4e304e2dc8be074bd212a62c3 GIT binary patch literal 67210 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 XPRGXXc+W<_xi~qo>FLE3#IgSewv3c= literal 0 HcmV?d00001 diff --git a/doc/dependency.tex b/doc/dependency.tex new file mode 100644 index 00000000..1aad3afd --- /dev/null +++ b/doc/dependency.tex @@ -0,0 +1,197 @@ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: + + + +\documentclass[a4paper,11pt]{article} +\usepackage{graphicx} +\usepackage{algorithm} +\usepackage{algorithmic} +\usepackage{amsmath} +\usepackage{amstext} +\usepackage{amsfonts} +\usepackage{amsbsy} +\usepackage{amsthm} +\usepackage{prettyref} +%\newrefformat{alg}{Algorithm~\ref{#1}} +%\newrefformat{eq}{Equation~\ref{#1}} +%\newrefformat{lem}{Lemma~\ref{#1}} +%\newrefformat{thm}{Theorem~\ref{#1}} +%\newrefformat{chp}{Chapter~\ref{#1}} +%\newrefformat{sec}{Section~\ref{#1}} +%\newrefformat{apx}{Appendix~\ref{#1}} +%\newrefformat{tab}{Table~\ref{#1}} +%\newrefformat{fig}{Figure~\ref{#1}} + + +%usepackage[active]{srcltx} +\title{ Dependency Resolution in PISI} + +\author{Eray \"{O}zkural} + +\date{\today} + +\begin{document} + +\maketitle + + + +\section{Introduction} + +Dependency resolution in package management systems have a +significance in that they are the key to providing system stability +and internet upgrades. The scale of package databases requires the +dependency resolution mechanism to be efficient and correct, +motivating a closer look at the theory. + + +\section{Review} + +Dependency resolution has been taken in the most general setting as +the famous SAT problem of propositional logic. If we consider a system +$D$ of dependency statements $D_i$, each statement can be taken as a +proposition in propositional logic which states, for instance: + +$D_i$: if package $a$ is installed or package $b$ is installed, then +package $i$ is installable.\\ +... + +The system is thus understood as the conjunction of such facts, giving +us a logical programming formulation to determine installation conditions. + +Note that for simplicity we do not consider the nuances in upgrade and +remove operations at the moment. + +However, using a SAT solver for this operation may be shooting a fly +with a bazooka. We observe that only certain forms of propositions +will be necessary for a dependency system. Furthermore, as we shall +see further constraints and optimizations may be required of the +system that are not modelled well with the SAT problem. + +We use a graph theoretic approach instead. A directed graph (digraph) +$G=(V,E)$ is formally a set of vertices $V$ and a set of edges $E$ +where each edge $(u,v)$ represents an edge from a vertex to +another. Topological sort of a graph gives a total ordering of the +vertices in which there are only forward edges. + +\section{Package operation planning} + +The dependency resolution problem may be viewed as a simple forward +chaining problem, where we would like to begin from an initial state +$S_0$ and by following allowable system transitions $t_i: S -> S$, +arrive at a desired system state $S_f$. + +A system state $S_i$ is defined as the set of installed packages on the +system together with their versions, i.e. $S_i = \{ (x,v) : x is +installed, v=version(x)\} $. An atomic system transition $t_i$ chains one +system state into another, making one ACID change on the system. The +usual atomic transitions are the single package install, remove and +upgrade operations found in low-level package management code. + +A package operation plan is thus naturally conceived of as a sequence +of atomic system transitions. Given an initial state and a final +state, the job of the package operation planner is to determine +whether there is a plan, and if so find the "best" one. + +Where there are no versions involved (e.g. upgrade/downgrade), we will +replace the pair $(x,v)$ with $x$. + +\subsection{System consistency} + +It is worth mentioning here the concept of system consistency. As in a +database transaction, it is not acceptable that the system violates an +invariant afterwards. In the context of PISI, system consistency is +composed of two conditions for the current set of installed packages. +\begin{enumerate} +\item All package dependencies are satisfied (we may call this a + closed system) +\item No package conflicts are present. +\end{enumerate} + +Therefore, by atomic transition we also mean one that does not corrupt +system consistency. The system is thus never in an inconsistent state. + + +\subsection{Solving the simplest case with topological sorting} + +We will now concentrate on a simple form of the problem which can +be solved with topological sorting. This form is not concerned with +versions. From initial set of packages $S_0$, we would like to +install in addition a new set $A$ of packages obtaining $S_f = S_0 \cup +A$. + +The only relations considered are of the form: $a$ Depends on $b$, or more +briefly $aDb$. + +The graph of all such simple dependency relations is a directed graph +(digraph) $G$. For each dependency relation $aDB$, there is an edge $a +\to b$ in $G$. Accessing graph $G$ usually requires a database operation and +is therefore expensive. + +We now consider the digraph $G_A$ of the minimal set of simple +dependency relations which contains all information required to +construct a plan to install packages $A$. $G_A$ is a vertex induced graph +such that the fringe of $A$, e.g. vertices with out-degree $0$ are +already installed. Vertices of $G_A$ are taken from $S_f$. First, let us +explain the labelling scheme. Already installed vertices are labelled +with 'i'. Packages to be added are labelled with 'a', and packages to +be installed due to dependencies are labelled with 'd'. We +construct the graph as follows +\begin{algorithm} + %\caption{$\textsc{Par-Freq}(T_i, \epsilon, \textsc{Mine-Freq} )$} + \label{alg:cons-graph} + \begin{algorithmic}[1] +\STATE $G_A \gets$ isolated vertex set $A$ labelled with 'a' +\REPEAT + \STATE done $\gets$ true + \FOR{each $u \in V_A$ with out-degree $0$} + \FOR{ $v \in adj(u) $ of $G$} + \IF{$v is \notin V_A$} + \STATE done $\gets$ false + \IF{$v$ is installed} + \STATE label $v$ with 'i' + \ELSE + \STATE label $v$ with 'd' + \ENDIF + \STATE add $(u,v)$ to $G_A$ + \ENDIF + \ENDFOR + \ENDFOR +\UNTIL{done} +\end{algorithmic} +\end{algorithm} + +By this iterative expansion, we do a minimum number of database +accesses to $G$ and construct a dependency graph in memory. If the +$G_A$'s fringe has vertices with non 'i'-labels, then $A$ cannot be +installed. Otherwise, we find a topological sort $L$ of $G_A$, and in +the reverse order, install packages for vertices labelled with +'a' or 'd'. + +\section{Complex cases} + +\subsection{A complex upgrade} + +plan: upgrade $(a,1)$ to $(a,2)$\\ +\\ +rules: + $(a,1)$ depends on $(b,1), (c,1)$ \\ + $(a,1)$ conflicts with $(d,1)$\\ + $(a,2)$ depends on $(c,3), (d,2)$\\ + $(a,2)$ conflicts with $(b,1)$\\ +\\ +initial state:\\ + $(a,1), (b,1), (c,1)$ installed \\ +\\ +plan:\\ + remove $(b,1)$\\ + upgrade $(c,1) -> (c,3)$\\ + install $(d,2)$\\ + upgrade $(a,1) -> (a,2)$\\ + + +\end{document} diff --git a/doc/dependency.txt b/doc/dependency.txt deleted file mode 100644 index 50078fdd..00000000 --- a/doc/dependency.txt +++ /dev/null @@ -1,141 +0,0 @@ -Dependency Resolution in PISI - -Eray Ozkural - - - -1. Introduction - -Dependency resolution in package management systems have a -significance in that they are the key to providing system stability -and internet upgrades. The scale of package databases requires the -dependency resolution mechanism to be efficient and correct, -motivating a closer look at the theory. - - -2. Review - -Dependency resolution has been taken in the most general setting as -the famous SAT problem of propositional logic. If we consider a system -D of dependency statements D_i, each statement can be taken as a -proposition in propositional logic which states, for -instance: - -D_i: if package a is installed or package b is installed, then package i -is installable. -... - -The system is thus understood as the conjunction of such facts, giving -us a logical programming system for determining installation conditions. - -Note that for simplicity we do not consider the nuances in upgrade and -remove operations at the moment. - -However, using a SAT solver for this operation may be shooting a fly -with a bazooka. We observe that only certain forms of propositions -will be necessary for a dependency system. Furthermore, as we shall -see further constraints and optimizations may be required of the -system that are not modelled well with SAT problem. - - -3. Package operation planning - -The dependency resolution problem may be viewed as a simple forward -chaining problem, where we would like to begin from an initial state -S_0 and by following allowable system transitions t_i: S -> S, -arrive at a desired system state S_f. - -A system state S_i is defined as the set of installed packages on the -system together with their versions, i.e. S_i = { (x,v) : x is -installed, v=version(x)}. An atomic system transition t_i chains one -system state into another, making one ACID change on the system. The -usual atomic transitions are the single package install, remove and -upgrade operations found in low-level package management code. - -A package operation plan is thus naturally conceived of as a sequence -of atomic system transitions. Given an initial state and a final -state, the job of the package operation planner is to determine -whether there is a plan, and if so find the "best" one. - -Where there are no versions involved (e.g. upgrade/downgrade), we will -replace the pair (x,v) with x. - -3.1 System consistency - -It is worth mentioning here the concept of system consistency. As in a -database transaction, it is not acceptable that the system violates an -invariant afterwards. In the context of PISI, system consistency is -composed of two conditions for the current set of installed packages. - 1. All package dependencies are satisfied (we may call this a closed system) - 2. No package conflicts are present. - -Therefore, by atomic transition we also mean one that does not corrupt -system consistency. The system is thus never in an inconsistent state. - - -3.2 Solving the simplest case with topological sorting - -We will now concentrate on a simple form of the problem which can -be solved with topological sorting. This form is not concerned with -versions. From initial set of packages S_0, we would like to -install in addition a new set A of packages obtaining S_f = S_0 \cup A. - -The only relations considered are of the form: a Depends on b, or more -shortly aDb. - -The graph of all such simple dependency relations is a directed graph -(digraph) G. For each dependency relation aDB, there is an edge a -> -b in G. Accessing graph G usually requires a database operation and -is therefore expensive. - -We now consider the digraph G_A of the minimal set of simple -dependency relations which contains all information required to -construct a plan to install packages A. G_A is a vertex induced graph -such that the fringe of $A$, e.g. vertices with out-degree $0$ are -already installed. Vertices of G_A are taken from S_f. First, let us -explain the labelling scheme. Already installed vertices are labelled -with 'i'. Packages to be added are labelled with 'a', and packages to -be installed due to dependencies are labelled with 'd'. We -construct the graph as follows - - G_A <- isolated vertex set A labelled with 'a' - repeat - done <- true - for each u in V_A with out-degree 0 - for v in adj(u) in G - if v is not in V_A - done <- false - if v is installed - label v with 'i' - else - label v with 'd' - add (u,v) to G_A - until done - -By this iterative expansion, we do a minimum number of database -accesses to G and construct a dependency graph in memory. If the -G_A's fringe has vertices with non 'i'-labels, then A cannot be -installed. Otherwise, we find a topological sort L of G_A, and in -the reverse order, install packages for vertices labelled with -'a' or 'd'. - -4. Complex cases - -4.1 A complex upgrade - -plan: upgrade (a,1) to (a,2) - -rules: - (a,1) depends on (b,1), (c,1) - (a,1) conflicts with (d,1) - (a,2) depends on (c,3), (d,2) - (a,2) conflicts with (b,1) - -initial state: - (a,1), (b,1), (c,1) installed - -plan: - remove (b,1) - upgrade (c,1) -> (c,3) - install (d,2) - upgrade (a,1) -> (a,2) diff --git a/doc/prettyref.sty b/doc/prettyref.sty new file mode 100644 index 00000000..67940f3b --- /dev/null +++ b/doc/prettyref.sty @@ -0,0 +1,37 @@ +%% +%% This is file `prettyref.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% prettyref.dtx (with options: `style') +%% +%% Copyright (c) 1995 Kevin Ruland +%% +%% +%% prettyref v3.0 +%% +%% Copyright 1995,1998. by Kevin Ruland kevin@rodin.wustl.edu +%% +\ProvidesPackage{prettyref}[1998/07/09 v3.0] +\def\newrefformat#1#2{% + \@namedef{pr@#1}##1{#2}} +\newrefformat{eq}{\textup{(\ref{#1})}} +\newrefformat{lem}{Lemma \ref{#1}} +\newrefformat{thm}{Theorem \ref{#1}} +\newrefformat{cha}{Chapter \ref{#1}} +\newrefformat{sec}{Section \ref{#1}} +\newrefformat{tab}{Table \ref{#1} on page \pageref{#1}} +\newrefformat{fig}{Figure \ref{#1} on page \pageref{#1}} +\def\prettyref#1{\@prettyref#1:} +\def\@prettyref#1:#2:{% + \expandafter\ifx\csname pr@#1\endcsname\relax% + \PackageWarning{prettyref}{Reference format #1\space undefined}% + \ref{#1:#2}% + \else% + \csname pr@#1\endcsname{#1:#2}% + \fi% +} +\endinput +%% +%% End of file `prettyref.sty'.