Changeset 489d3ba for doc


Ignore:
Timestamp:
Nov 15, 2024, 5:48:11 PM (5 weeks ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
e255902b
Parents:
2325b57
Message:

change how latex code generated from sharing-demo.cfa

Location:
doc/theses/mike_brooks_MMath
Files:
3 edited
1 moved

Legend:

Unmodified
Added
Removed
  • doc/theses/mike_brooks_MMath/Makefile

    r2325b57 r489d3ba  
    1010TeXSRC = ${wildcard *.tex}
    1111PicSRC = ${notdir ${wildcard ${Pictures}/*.png}}
    12 DemoSRC = ${notdir ${wildcard ${Programs}/*-demo.cfa}}
     12DemoPgmSRC = ${notdir ${wildcard ${Programs}/*-demo.cfa}}
    1313PgmSRC = ${notdir ${wildcard ${Programs}/*}}
    1414RunPgmSRC = ${notdir ${wildcard ${Programs}/*.run.*}}
     
    2424BASE = ${basename ${DOCUMENT}}                  # remove suffix
    2525
    26 DemoTex = ${DemoSRC:%.cfa=${Build}/%.tex}
    2726RunPgmExe = ${addprefix ${Build}/,${basename ${basename ${RunPgmSRC}}}}
    2827RunPgmOut = ${RunPgmExe:%=%.out}
     28DemoPgmExe = ${addprefix ${Build}/,${basename ${basename ${DemoPgmSRC}}}}
     29DemoPgmOut = ${DemoPgmExe:%=%.out}
    2930
    3031# Commands
     
    3839# Rules and Recipes
    3940
    40 .PHONY : all fragments_ran clean                        # not file names
    41 .PRECIOUS : ${Build}/% ${Build}/%-demo      # don't delete intermediates
     41.PHONY : all clean                              # not file names
     42.SECONDARY:
     43#.PRECIOUS : ${Build}/%                         # don't delete intermediates
    4244.ONESHELL :
    4345
    44 all : fragments_ran ${DOCUMENT}
    45 
    46 fragments_ran : $(RunPgmOut)
     46all : ${DOCUMENT}
    4747
    4848clean :
     
    5151# File Dependencies
    5252
    53 %.pdf : ${TeXSRC} ${DemoTex} ${PicSRC} ${PgmSRC} ${BibSRC} ${BibRep}/pl.bib ${LaTMac}/common.tex Makefile | ${Build}
     53%.pdf : ${TeXSRC} $(RunPgmOut) ${DemoPgmOut} ${PicSRC} ${BibSRC} ${BibRep}/pl.bib ${LaTMac}/common.tex Makefile | ${Build}
    5454        ${LaTeX} ${BASE}
    5555        ${BibTeX} ${Build}/${BASE}
     
    6464        mkdir -p $@
    6565
    66 %-demo.tex: %-demo | ${Build}
    67         $< > $@
     66${Build}/%-demo: ${Programs}/%-demo.cfa | ${Build}
     67        ${CFA} $< -o $@
    6868
    69 ${Build}/%-demo: ${Programs}/%-demo.cfa | ${Build}
     69${Build}/%: ${Programs}/%-demo.cfa | ${Build}
    7070        ${CFA} $< -o $@
    7171
  • doc/theses/mike_brooks_MMath/programs/sharing-demo.cfa

    r2325b57 r489d3ba  
    55#define str(s) #s
    66
     7ofstream outfile;
     8
    79void demo1() {
    810        sout | sepOff;
    9         sout | "Consider two strings @s1@ and @s1a@ that are in an aliasing relationship, and a third, @s2@, made by a simple copy from @s1@.";
    10         sout | "\\par\\noindent";
    11         sout | "\\begin{tabular}{llll}";
    12         sout | "\t\t\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
     11//      sout | "Consider two strings @s1@ and @s1a@ that are in an aliasing relationship, and a third, @s2@, made by a simple copy from @s1@.";
    1312
    1413        #define S1 string s1  = "abc"
     
    2120        assert( s1a == "abc" );
    2221        assert( s2 == "abc" );
    23         sout | xstr(S1) | "\t\\\\";
    24         sout | xstr(S1A) | "\t\\\\";
    25         sout | xstr(S2) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2;
    26         sout | "\\end{tabular}";
    27         sout | "\\par\\noindent";
    28 
    29         sout | "Aliasing (@`shareEdits@) means that changes flow in both directions; with a simple copy, they do not.";
    30         sout | "\\par\\noindent";
    31         sout | "\\begin{tabular}{llll}";
    32         sout | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
    33         sout | "\t\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     22
     23        open( outfile, "build/sharing1.tex" );
     24        outfile | "\\begin{cquote}";
     25        outfile | "\\begin{tabular}{@{}llll@{}}";
     26        outfile | "\t\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
     27        outfile | xstr(S1) | "\t\\\\";
     28        outfile | xstr(S1A) | "\t\\\\";
     29        outfile | xstr(S2) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2;
     30        outfile | "\\end{tabular}";
     31        outfile | "\\end{cquote}";
     32        close( outfile );
     33
     34//      sout | "Aliasing (@`shareEdits@) means that changes flow in both directions; with a simple copy, they do not.";
     35        open( outfile, "build/sharing2.tex" );
     36        outfile | "\\begin{cquote}";
     37        outfile | "\\begin{tabular}{@{}llll@{}}";
     38        outfile | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
     39        outfile | "\\multicolumn{1}{r}{initial} & " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    3440
    3541        #define S1s1 s1 [1] = '+'
    3642        S1s1;
    3743        assert( s1 == "a+c" );
    38         sout | xstr(S1s1) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     44        outfile | xstr(S1s1) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    3945
    4046        #define S1As1 s1a[1] = '-'
    4147        S1As1;
    4248        assert( s1a == "a-c" );
    43         sout | xstr(S1As1) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     49        outfile | xstr(S1As1) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    4450
    4551        #define S2s1 s2 [1] = '|'
    4652        S2s1;
    4753        assert( s2 == "a|c" );
    48         sout | xstr(S2s1) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2;
    49         sout | "\\end{tabular}";
    50         sout | "\\par\\noindent";
    51 
    52         sout | "Assignment of a value is just a modificiation."
    53                    "\nThe aliasing relationship is established at construction and is unaffected by assignment of a value.";
    54         sout | "\\par\\noindent";
    55         sout | "\\begin{tabular}{llll}";
    56         sout | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
    57         sout | "\t\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     54        outfile | xstr(S2s1) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2;
     55        outfile | "\\end{tabular}";
     56        outfile | "\\end{cquote}";
     57        close( outfile );
     58
     59//      sout | "Assignment of a value is just a modificiation."
     60//                 "\nThe aliasing relationship is established at construction and is unaffected by assignment of a value.";
     61        open( outfile, "build/sharing3.tex" );
     62        outfile | "\\begin{cquote}";
     63        outfile | "\\begin{tabular}{llll}";
     64        outfile | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
     65        outfile | "\\multicolumn{1}{r}{initial} & " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    5866
    5967        #define S1qrs s1  = "qrs"
    6068        S1qrs;
    6169        assert( s1 == "qrs" );
    62         sout | xstr(S1qrs) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     70        outfile | xstr(S1qrs) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    6371
    6472        #define S1Atuv s1a = "tuv"
    6573        S1Atuv;
    6674        assert( s1a == "tuv" );
    67         sout | xstr(S1Atuv) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     75        outfile | xstr(S1Atuv) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    6876
    6977        #define S2wxy s2  = "wxy"
    7078        S2wxy;
    7179        assert( s2 == "wxy" );
    72         sout | xstr(S2wxy) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2;
    73         sout | "\\end{tabular}";
    74         sout | "\\par\\noindent";
    75 
    76         sout | "Assignment from a string is just assignment of a value."
    77                    "\nWhether of not the RHS participates in aliasing is irrelevant.  Any aliasing of the LHS is unaffected.";
    78         sout | "\\par\\noindent";
    79         sout | "\\begin{tabular}{llll}";
    80         sout | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
    81         sout | "\t\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     80        outfile | xstr(S2wxy) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2;
     81        outfile | "\\end{tabular}";
     82        outfile | "\\end{cquote}";
     83        close( outfile );
     84
     85//      sout | "Assignment from a string is just assignment of a value."
     86//                 "\nWhether of not the RHS participates in aliasing is irrelevant.  Any aliasing of the LHS is unaffected.";
     87        open( outfile, "build/sharing4.tex" );
     88        outfile | "\\begin{cquote}";
     89        outfile | "\\begin{tabular}{llll}";
     90        outfile | "\t\t& @s1@\t& @s1a@\t& @s2@\t\\\\";
     91        outfile | "\\multicolumn{1}{r}{initial} & " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    8292
    8393        #define S1S2 s1  = s2
     
    8696        assert( s1a == "wxy" );
    8797        assert( s2 == "wxy" );
    88         sout | xstr(S1S2) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     98        outfile | xstr(S1S2) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    8999
    90100        #define S1aaa s1  = "aaa"
     
    93103        assert( s1a == "aaa" );
    94104        assert( s2 == "wxy" );
    95         sout | xstr(S1aaa) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     105        outfile | xstr(S1aaa) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    96106
    97107        #define S2S1 s2  = s1
     
    100110        assert( s1a == "aaa" );
    101111        assert( s2 == "aaa" );
    102         sout | xstr(S2S1) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     112        outfile | xstr(S2S1) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    103113
    104114        #define S2bbb s2  = "bbb"
     
    107117        assert( s1a == "aaa" );
    108118        assert( s2 == "bbb" );
    109         sout | xstr(S2bbb) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     119        outfile | xstr(S2bbb) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    110120
    111121        #define S2S1a s2  = s1a
     
    114124        assert( s1a == "aaa" );
    115125        assert( s2 == "aaa" );
    116         sout | xstr(S2S1a) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     126        outfile | xstr(S2S1a) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    117127
    118128        #define S2ccc s2  = "ccc"
     
    121131        assert( s1a == "aaa" );
    122132        assert( s2 == "ccc" );
    123         sout | xstr(S2ccc) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     133        outfile | xstr(S2ccc) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    124134
    125135        #define S1xxx s1  = "xxx"
     
    128138        assert( s1a == "xxx" );
    129139        assert( s2 == "ccc" );
    130         sout | xstr(S1xxx) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
    131         sout | "\\end{tabular}";
    132         sout | "\\par";
     140        outfile | xstr(S1xxx) | "\t& " | s1 | "\t& " | s1a | "\t& " | s2 | "\t\\\\";
     141        outfile | "\\end{tabular}";
     142        outfile | "\\end{cquote}";
     143        close( outfile );
    133144}
    134145
    135146
    136147void demo2() {
    137         sout | "Consider new strings @s1_mid@ being an alias for a run in the middle of @s1@, along with @s2@, made by a simple copy from the middle of @s1@.";
    138         sout | "\\par\\noindent";
    139         sout | "\\begin{tabular}{llll}";
    140         sout | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
     148//      sout | "Consider new strings @s1_mid@ being an alias for a run in the middle of @s1@, along with @s2@, made by a simple copy from the middle of @s1@.";
     149        open( outfile, "build/sharing5.tex" );
     150        outfile | "\\begin{cquote}";
     151        outfile | "\\begin{tabular}{llll}";
     152        outfile | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
    141153
    142154        #define D2_s1_abcd string s1     = "abcd"
    143155        D2_s1_abcd;
    144         sout | xstr(D2_s1_abcd) | "\t\\\\";
     156        outfile | xstr(D2_s1_abcd) | "\t\\\\";
    145157
    146158        #define D2_s1mid_s1 string s1_mid = s1(1,2)`shareEdits
    147159        D2_s1mid_s1;
    148         sout | xstr(D2_s1mid_s1) | "\t\\\\";
     160        outfile | xstr(D2_s1mid_s1) | "\t\\\\";
    149161
    150162        #define D2_s2_s1 string s2     = s1(1,2)
     
    153165        assert( s1_mid == "bc" );
    154166        assert( s2 == "bc" );
    155         sout | xstr(D2_s2_s1) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
    156         sout | "\\end{tabular}";
    157         sout | "\\par\\noindent";
    158 
    159         sout | "Again, @`shareEdits@ passes changes in both directions; copy does not.  Note the difference in index values, with the \\emph{b} position being 1 in the longer string and 0 in the shorter strings.  In the case of s1 aliasing with @s1_mid@, the very same character is being accessed by different postitions.";
    160         sout | "\\par\\noindent";
    161         sout | "\\begin{tabular}{llll}";
    162         sout | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
    163         sout | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
     167        outfile | xstr(D2_s2_s1) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
     168        outfile | "\\end{tabular}";
     169        outfile | "\\end{cquote}";
     170        close( outfile );
     171
     172//      sout | "Again, @`shareEdits@ passes changes in both directions; copy does not.  Note the difference in index values, with the \\emph{b} position being 1 in the longer string and 0 in the shorter strings.  In the case of s1 aliasing with @s1_mid@, the very same character is being accessed by different postitions.";
     173        open( outfile, "build/sharing6.tex" );
     174        outfile | "\\begin{cquote}";
     175        outfile | "\\begin{tabular}{llll}";
     176        outfile | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
     177        outfile | "\\multicolumn{1}{r}{initial} & " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
    164178
    165179        #define D2_s1_plus s1    [1] = '+'
     
    168182        assert( s1_mid == "+c" );
    169183        assert( s2 == "bc" );
    170         sout | xstr(D2_s1_plus) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
     184        outfile | xstr(D2_s1_plus) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
    171185
    172186        #define D2_s1mid_minus s1_mid[0] = '-'
     
    175189        assert( s1_mid == "-c" );
    176190        assert( s2 == "bc" );
    177         sout | xstr(D2_s1mid_minus) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
     191        outfile | xstr(D2_s1mid_minus) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
    178192
    179193        #define D2_s2_pipe s2    [0] = '|'
     
    182196        assert( s1_mid == "-c" );
    183197        assert( s2 == "|c" );
    184         sout | xstr(D2_s2_pipe) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
    185         sout | "\\end{tabular}";
    186         sout | "\\par\\noindent";
    187 
    188         sout | "Once again, assignment of a value is a modificiation that flows through the aliasing relationship, without affecting its structure.";
    189         sout | "\\par\\noindent";
    190         sout | "\\begin{tabular}{llll}";
    191         sout | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
    192         sout | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
     198        outfile | xstr(D2_s2_pipe) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
     199        outfile | "\\end{tabular}";
     200        outfile | "\\end{cquote}";
     201        close( outfile );
     202
     203//      sout | "Once again, assignment of a value is a modificiation that flows through the aliasing relationship, without affecting its structure.";
     204        open( outfile, "build/sharing7.tex" );
     205        outfile | "\\begin{cquote}";
     206        outfile | "\\begin{tabular}{llll}";
     207        outfile | "\t\t\t\t& @s1@\t& @s1_mid@\t& @s2@\t\\\\";
     208        outfile | "\\multicolumn{1}{r}{initial} & " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
    193209
    194210        #define D2_s1mid_ff s1_mid = "ff"
     
    197213        assert( s1_mid == "ff" );
    198214        assert( s2 == "|c" );
    199         sout | xstr(D2_s1mid_ff) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
     215        outfile | xstr(D2_s1mid_ff) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
    200216
    201217        #define D2_s2_gg s2     = "gg"
     
    204220        assert( s1_mid == "ff" );
    205221        assert( s2 == "gg" );
    206         sout | xstr(D2_s2_gg) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
    207         sout | "\\end{tabular}";
    208         sout | "\\par\\noindent";
    209 
    210         sout | "In the \\emph{ff} step, which is a positive example of flow across an aliasing relationship, the result is straightforward to accept because the flow direction is from contained (small) to containing (large).  The following rules for edits through aliasing substrings will guide how to flow in the opposite direction.";
    211         sout | "\\par";
    212 
    213 
    214         sout | "Growth and shrinkage are natural extensions.  An empty substring is a real thing, at a well-defined location, whose meaning is extrapolated from the examples so far.  The intended metaphor is to operating a GUI text editor.  Having an aliasing substring is like using the mouse to select a few words.  Assigning onto an aliasign substring is like typing from having a few words selected:  depending how much you type, the file being edited can get shorter or longer.";
    215         sout | "\\par\\noindent";
    216         sout | "\\begin{tabular}{lll}";
    217         sout | "\t\t\t\t& @s1@\t& @s1_mid@\t\\\\";
    218         sout | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
     222        outfile | xstr(D2_s2_gg) | "\t& " | s1 | "\t& " | s1_mid | "\t& " | s2 | "\t\\\\";
     223        outfile | "\\end{tabular}";
     224        outfile | "\\end{cquote}";
     225        close( outfile );
     226
     227//      sout | "In the \\emph{ff} step, which is a positive example of flow across an aliasing relationship, the result is straightforward to accept because the flow direction is from contained (small) to containing (large).  The following rules for edits through aliasing substrings will guide how to flow in the opposite direction.";
     228//      sout | "\\par";
     229
     230
     231//      sout | "Growth and shrinkage are natural extensions.  An empty substring is a real thing, at a well-defined location, whose meaning is extrapolated from the examples so far.  The intended metaphor is to operating a GUI text editor.  Having an aliasing substring is like using the mouse to select a few words.  Assigning onto an aliasign substring is like typing from having a few words selected:  depending how much you type, the file being edited can get shorter or longer.";
     232        open( outfile, "build/sharing8.tex" );
     233        outfile | "\\begin{cquote}";
     234        outfile | "\\begin{tabular}{lll}";
     235        outfile | "\t\t\t\t& @s1@\t& @s1_mid@\t\\\\";
     236        outfile | "\\multicolumn{1}{r}{initial} & " | s1 | "\t& " | s1_mid | "\t\\\\";
    219237
    220238        assert( s1 == "affd" );
    221239//      assert( s1_mid == "fc" );                                                                                                        // ????????? bug?
    222         sout | xstr(D2_s2_gg) | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
     240        outfile | xstr(D2_s2_gg) | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
    223241
    224242        #define D2_s1mid_hhhh s1_mid = "hhhh"
     
    226244        assert( s1 == "ahhhhd" );
    227245        assert( s1_mid == "hhhh" );
    228         sout  | xstr(D2_s1mid_hhhh)  | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
     246        outfile  | xstr(D2_s1mid_hhhh)  | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
    229247
    230248        #define D2_s1mid_i s1_mid = "i"
     
    232250        assert( s1 == "aid" );
    233251        assert( s1_mid == "i" );
    234         sout  | xstr(D2_s1mid_i)  | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
     252        outfile  | xstr(D2_s1mid_i)  | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
    235253
    236254        #define D2_s1mid_empty s1_mid = ""
     
    238256        assert( s1 == "ad" );
    239257        // assert( s1_mid == "" );    ------ Should be so, but fails
    240         sout  | xstr(D2_s1mid_empty)  | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
     258        outfile  | xstr(D2_s1mid_empty)  | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
    241259
    242260        #define D2_s1mid_jj s1_mid = "jj"
     
    244262        assert( s1 == "ajjd" );
    245263        assert( s1_mid == "jj" );
    246         sout  | xstr(D2_s1mid_jj)  | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
    247         sout | "\\end{tabular}";
    248         sout | "\\par\\noindent";
    249 
    250         sout | "Multiple portions can be aliased.  When there are several aliasing substrings at once, the text editor analogy becomes an online multi-user editor.  I should be able to edit a paragraph in one place (changing the document's length), without my edits affecting which letters are within a mouse-selection that you had made previously, somewhere else.";
    251         sout | "\\par\\noindent";
    252         sout | "\\begin{tabular}{lllll}";
    253         sout | "\t\t\t\t& @s1@\t& @s1_bgn@\t& @s1_mid@\t& @s1_end@\t\\\\";
     264        outfile  | xstr(D2_s1mid_jj)  | "\t& " | s1 | "\t& " | s1_mid | "\t\\\\";
     265        outfile | "\\end{tabular}";
     266        outfile | "\\end{cquote}";
     267        close( outfile );
     268
     269//      sout | "Multiple portions can be aliased.  When there are several aliasing substrings at once, the text editor analogy becomes an online multi-user editor.  I should be able to edit a paragraph in one place (changing the document's length), without my edits affecting which letters are within a mouse-selection that you had made previously, somewhere else.";
     270        open( outfile, "build/sharing9.tex" );
     271        outfile | "\\begin{cquote}";
     272        outfile | "\\begin{tabular}{lllll}";
     273        outfile | "\t\t\t\t& @s1@\t& @s1_bgn@\t& @s1_mid@\t& @s1_end@\t\\\\";
    254274
    255275        #define D2_s1bgn_s1     string s1_bgn = s1(0, 1)`shareEdits
    256276        D2_s1bgn_s1;
    257         sout  | xstr(D2_s1bgn_s1)  | "\t\\\\";
     277        outfile  | xstr(D2_s1bgn_s1)  | "\t\\\\";
    258278
    259279        #define D2_s1end_s1 string s1_end = s1(3, 1)`shareEdits
     
    263283        assert( s1_mid == "jj" );
    264284        assert( s1_end == "d" );
    265         sout  | xstr(D2_s1end_s1)  | "\t& " | s1 | "\t& " | s1_bgn | "\t& " | s1_mid | "\t& " | s1_end | "\t\\\\";
     285        outfile  | xstr(D2_s1end_s1)  | "\t& " | s1 | "\t& " | s1_bgn | "\t& " | s1_mid | "\t& " | s1_end | "\t\\\\";
    266286
    267287        #define D1_s1bgn_zzz s1_bgn = "zzzz"
     
    271291        assert( s1_mid == "jj" );
    272292        assert( s1_end == "d" );
    273         sout  | xstr(D1_s1bgn_zzz)  | "\t& " | s1 | "\t& " | s1_bgn | "\t& " | s1_mid | "\t& " | s1_end | "\t\\\\";
    274         sout | "\\end{tabular}";
    275         sout | "\\par\\noindent";
    276 
    277         sout | "When an edit happens on an aliasing substring that overlaps another, an effect is unavoidable.  Here, the passive party sees its selection shortened, to exclude the characters that were not part of the original selection.";
    278         sout | "\\par\\noindent";
    279         sout | "\\begin{tabular}{llllll}";
    280         sout | "\t\t\t\t& @s1@\t& @s1_bgn@\t& @s1_crs@\t& @s1_mid@\t& @s1_end@\t\\\\";
     293        outfile  | xstr(D1_s1bgn_zzz)  | "\t& " | s1 | "\t& " | s1_bgn | "\t& " | s1_mid | "\t& " | s1_end | "\t\\\\";
     294        outfile | "\\end{tabular}";
     295        outfile | "\\end{cquote}";
     296        close( outfile );
     297
     298//      sout | "When an edit happens on an aliasing substring that overlaps another, an effect is unavoidable.  Here, the passive party sees its selection shortened, to exclude the characters that were not part of the original selection.";
     299        open( outfile, "build/sharing10.tex" );
     300        outfile | "\\begin{cquote}";
     301        outfile | "\\begin{tabular}{llllll}";
     302        outfile | "\t\t\t\t& @s1@\t& @s1_bgn@\t& @s1_crs@\t& @s1_mid@\t& @s1_end@\t\\\\";
    281303
    282304        #define D2_s1crs_s1 string s1_crs = s1(3, 2)`shareEdits
     
    287309        assert( s1_mid == "jj" );
    288310        assert( s1_end == "d" );
    289         sout  | xstr(D2_s1crs_s1)  | "\t& " | s1 | "\t& " | s1_bgn | "\t& " | s1_crs | "\t& " | s1_mid | "\t& " | s1_end | "\t\\\\";
     311        outfile  | xstr(D2_s1crs_s1)  | "\t& " | s1 | "\t& " | s1_bgn | "\t& " | s1_crs | "\t& " | s1_mid | "\t& " | s1_end | "\t\\\\";
    290312
    291313        #define D2_s1crs_ppp s1_crs = "+++"
     
    296318        assert( s1_mid == "j" );
    297319        assert( s1_end == "d" );
    298         sout  | xstr(D2_s1crs_ppp)  | "\t& " | s1 | "\t& " | s1_bgn | "\t& " | s1_crs | "\t& " | s1_mid | "\t& " | s1_end | "\t\\\\";
    299         sout | "\\end{tabular}";
    300         sout | "\\par\\noindent";
    301         sout | "TODO: finish typesetting the demo";
     320        outfile  | xstr(D2_s1crs_ppp)  | "\t& " | s1 | "\t& " | s1_bgn | "\t& " | s1_crs | "\t& " | s1_mid | "\t& " | s1_end | "\t\\\\";
     321        outfile | "\\end{tabular}";
     322        outfile | "\\end{cquote}";
     323        close( outfile );
    302324
    303325        // "This shortening behaviour means that a modification has to occur entirely inside a substring, to show up in that substring.  Sharing changes through the intersection of partially overlapping aliases is still possible, so long as the receiver's boundary is not inside the edit."
     
    379401        demo1();
    380402        demo2();
    381         printf("%% %s done running\n", argv[0]);
     403//      printf("%% %s done running\n", argv[0]);
    382404}
  • doc/theses/mike_brooks_MMath/string.tex

    r2325b57 r489d3ba  
    6767\CFA provides a dynamic mechanism to indicate mutable or immutable as an assignment attribute: @`shareEdits@.
    6868
    69 \input{sharing-demo.tex}
    70 
    7169Consider two strings @s1@ and @s1a@ that are in an aliasing relationship, and a third, @s2@, made by a simple copy from @s1@.
    72 \par\noindent
    73 \begin{tabular}{llll}
    74                                 & @s1@  & @s1a@ & @s2@  \\
    75 %\input{sharing-demo1.tex}
    76 \end{tabular}
    77 \par\noindent
     70Aliasing (@`shareEdits@) means that changes flow in both directions; with a simple copy, they do not.
     71\input{sharing1.tex}
     72
     73Aliasing (@`shareEdits@) means that changes flow in both directions; with a simple copy, they do not.
     74\input{sharing2.tex}
     75
     76Assignment of a value is just a modification.
     77The aliasing relationship is established at construction and is unaffected by assignment of a value.
     78\input{sharing3.tex}
     79
     80Assignment from a string is just assignment of a value.
     81Whether of not the RHS participates in aliasing is irrelevant.  Any aliasing of the LHS is unaffected.
     82\input{sharing4.tex}
     83
     84Consider new strings @s1_mid@ being an alias for a run in the middle of @s1@, along with @s2@, made by a simple copy from the middle of @s1@.
     85\input{sharing5.tex}
     86
     87Again, @`shareEdits@ passes changes in both directions; copy does not.
     88Note the difference in index values, with the \emph{b} position being 1 in the longer string and 0 in the shorter strings.
     89In the case of s1 aliasing with @s1_mid@, the very same character is being accessed by different positions.
     90\input{sharing6.tex}
     91
     92Once again, assignment of a value is a modification that flows through the aliasing relationship, without affecting its structure.
     93\input{sharing7.tex}
     94
     95In the \emph{ff} step, which is a positive example of flow across an aliasing relationship, the result is straightforward to accept because the flow direction is from contained (small) to containing (large).
     96The following rules for edits through aliasing substrings will guide how to flow in the opposite direction.
     97
     98Growth and shrinkage are natural extensions.
     99An empty substring is a real thing, at a well-defined location, whose meaning is extrapolated from the examples so far.
     100The intended metaphor is to operating a GUI text editor.
     101Having an aliasing substring is like using the mouse to select a few words.
     102Assigning onto an aliasing substring is like typing from having a few words selected: depending how much you type, the file being edited can get shorter or longer.
     103\input{sharing8.tex}
     104
     105Multiple portions can be aliased.
     106When there are several aliasing substrings at once, the text editor analogy becomes an online multi-user editor.
     107I should be able to edit a paragraph in one place (changing the document's length), without my edits affecting which letters are within a mouse-selection that you had made previously, somewhere else.
     108\input{sharing9.tex}
     109
     110When an edit happens on an aliasing substring that overlaps another, an effect is unavoidable.
     111Here, the passive party sees its selection shortened, to exclude the characters that were not part of the original selection.
     112\input{sharing10.tex}
     113
     114TODO: finish typesetting the demo
     115
     116%\input{sharing-demo.tex}
    78117
    79118
    80119\subsection{RAII limitations}
    81120
    82 Earlier work on \CFA [to cite Schluntz] implemented the feature of constructors and destructors.  A constructor is a user-defined function that runs implicitly, when control passes an object's declaration, while a destructor runs at the exit of the declaration's lexical scope.  The feature allows programmers to assume that, whenever a runtime object of a certain type is accessible, the system called one of the programmer's constructor functions on that object, and a matching destructor call will happen in the future.  The feature helps programmers know that their programs' invariants obtain.
    83 
    84 The purposes of such invariants go beyond ensuring authentic values for the bits inside the object.   These invariants can track occurrences of the managed objects in other data structures.  Reference counting is a typical application of the latter invariant type.  With a reference-counting smart pointer, the constructor and destructor \emph{of the pointer type} track the life cycles of occurrences of these pointers, by incrementing and decrementing a counter (usually) on the referent object, that is, they maintain a that is state separate from the objects to whose life cycles they are attached.  Both the \CC and \CFA RAII systems ares powerful enough to achieve such reference counting.
    85 
    86 The \CC RAII system supports a more advanced application.  A life cycle function has access to the object under management, by location; constructors and destructors receive a @this@ parameter providing its memory address.  A lifecycle-function implementation can then add its objects to a collection upon creation, and remove them at destruction.  A module that provides such objects, by using and encapsulating such a collection, can traverse the collection at relevant times, to keep the objects ``good.''  Then, if you are the user of such an module, declaring an object of its type means not only receiving an authentically ``good'' value at initialization, but receiving a subscription to a service that will keep the value ``good'' until you are done with it.
    87 
    88 In many cases, the relationship between memory location and lifecycle is simple.  But with stack-allocated objects being used as parameters and returns, there is a sender version in one stack frame and a receiver version in another.  \CC is able to treat those versions as distinct objects and guarantee a copy-constructor call for communicating the value from one to the other.  This ability has implications on the language's calling convention.  Consider an ordinary function @void f( Vehicle x )@, which receives an aggregate by value.  If the type @Vehicle@ has custom lifecycle functions, then a call to a user-provided copy constructor occurs, after the caller evaluates its argument expression, after the callee's stack frame exists, with room for its variable @x@ (which is the location that the copy-constructor must target), but before the user-provided body of @f@ begins executing.  \CC achieves this ordering by changing the function signature, in the compiled form, to pass-by-reference and having the callee invoke the copy constructor in its preamble.  On the other hand, if @Vehicle@ is a simple structure then the C calling convention is applied as the code originally appeared, that is, the call-site implementation code performs a bitwise copy from the caller's expression result, into the callee's x.
     121Earlier work on \CFA~\cite[ch.~2]{Schluntz17} implemented object constructors and destructors for all types (basic and user defined).
     122A constructor is a user-defined function run implicitly \emph{after} an object's declaration-storage is created, and a destructor is a user-defined function run \emph{before} an object's declaration-storage is deleted.
     123This feature guarantees pre invariants for users before accessing an object and post invariants for the programming environment after an object terminates.
     124
     125The purposes of these invariants goes beyond ensuring authentic values inside an object.
     126Invariants can also track occurrences of the managed objects in other data structures.
     127For example, reference counting is a typical application of an invariant outside of the data values.
     128With a reference-counting smart-pointer, the constructor and destructor \emph{of a pointer type} tracks the life cycle of the object it points to.
     129Both \CC and \CFA RAII systems are powerful enough to achieve reference counting.
     130
     131In general, a lifecycle function has access to an object by location, \ie constructors and destructors receive a @this@ parameter providing an object's memory address.
     132The lifecycle implementation can then add this object to a collection upon creation and remove it at destruction.
     133A module that provides such objects, by using and encapsulating such a collection, can traverse the collection at relevant times, to keep the objects ``good.''.
     134Hence, declaring such an object not only ensures ``good'' authentic at initialization, but also an implicit subscription to a service that keeps the value ``good'' across its lifetime.
     135
     136In many cases, the relationship between memory location and lifecycle is simple.
     137But with stack-allocated objects being used as parameters and returns, there is a sender version in one stack frame and a receiver version in another.
     138\CC is able to treat those versions as distinct objects and guarantee a copy-constructor call for communicating the value from one to the other.
     139This ability has implications on the language's calling convention.
     140Consider an ordinary function @void f( Vehicle x )@, which receives an aggregate by value.
     141If the type @Vehicle@ has custom lifecycle functions, then a call to a user-provided copy constructor occurs, after the caller evaluates its argument expression, after the callee's stack frame exists, with room for its variable @x@ (which is the location that the copy-constructor must target), but before the user-provided body of @f@ begins executing.
     142\CC achieves this ordering by changing the function signature, in the compiled form, to pass-by-reference and having the callee invoke the copy constructor in its preamble.
     143On the other hand, if @Vehicle@ is a simple structure then the C calling convention is applied as the code originally appeared, that is, the call-site implementation code performs a bitwise copy from the caller's expression result, into the callee's x.
    89144
    90145TODO: learn correction to fix inconsistency: this discussion says the callee invokes the copy constructor, but only the caller knows which copy constructor to use!
     
    149204
    150205The \CFA sting library provides the @string_sharectx@ type to control an ambient sharing context for the current thread.  It allows two adjustments: to opt out of sharing entirely, or to begin sharing within a private context.  Either way, the chosen mode applies to the current thread, for the duration of the lifetime of the created  @string_sharectx@ object, up to being suspended by child lifetimes of different contexts.  The indented use is with stack-managed lifetimes, in which the established context lasts until the current function returns, and affects all functions called that don't create their own contexts.
    151 \lstinputlisting[language=CFA, firstline=20, lastline=34]{sharectx-demo.cfa}
     206\lstinputlisting[language=CFA, firstline=20, lastline=34]{sharectx.run.cfa}
    152207In this example, the single-letter functions are called in alphabetic order.  The functions @a@ and @d@ share string character ranges within themselves, but not with each other.  The functions @b@, @c@ and @e@ never share anything.
    153208
     
    169224\subsection{Performance assessment}
    170225
    171 I assessed the CFA string library's speed and memory usage.  I present these results in even equivalent cases, due to either micro-optimizations foregone, or fundamental costs of the added functionality.  They also show the benefits and tradeoffs, as >100\% effects, of switching to CFA, with the tradeoff points quantified.  The final test shows the overall win of the CFA text-sharing mechanism.  It exercises several operations together, showing CFA enabling clean user code to achieve performance that STL requires less-clean user code to achieve.
    172 
    173 To discuss: general goal of ... while STL makes you think about memory management, all the time, and if you do your performance can be great ... CFA sacrifices this advantage modestly in exchange for big wins when you're not thinking about memory management.  [Does this position cover all of it?]
     226I assessed the \CFA string library's speed and memory usage.  I present these results in even equivalent cases, due to either micro-optimizations foregone, or fundamental costs of the added functionality.  They also show the benefits and tradeoffs, as >100\% effects, of switching to \CFA, with the tradeoff points quantified.  The final test shows the overall win of the \CFA text-sharing mechanism.  It exercises several operations together, showing \CFA enabling clean user code to achieve performance that STL requires less-clean user code to achieve.
     227
     228To discuss: general goal of ... while STL makes you think about memory management, all the time, and if you do your performance can be great ... \CFA sacrifices this advantage modestly in exchange for big wins when you're not thinking about memory management.  [Does this position cover all of it?]
    174229
    175230To discuss: revisit HL v LL APIs
     
    196251\subsubsection{Test: Append}
    197252
    198 This test measures the speed of appending fragments of text onto a growing string.  Its subcases include both CFA being similar to STL, and their designs offering a tradeoff.
     253This test measures the speed of appending fragments of text onto a growing string.  Its subcases include both \CFA being similar to STL, and their designs offering a tradeoff.
    199254
    200255One experimental variable is the user's operation being @a = a + b@ vs. @a += b@.  While experienced programmers expect the latter to be ``what you obviously should do,'' controlling the penalty of the former both helps the API be accessible to beginners and also helps offer confidence that when a user tries to compose operations, the forms that are most natural to the user's composition are viable.
     
    210265    @ } @                                      & @ } @
    211266\end{tabular}\\
    212 These benchmark drivers have an outer loop for ``until a sample-worthy amount of execution has happened'' and an inner loop for ``build up the desired-length string.''  It is sensible to doubt that a user should have to care about this difference, yet the STL performs differently in these cases.  Concretely, both cases incur the cost of copying characters into the target string, but only the allocation-fresh case incurs a further reallocation cost, which is generally paid at points of doubling the length.  For the STL, this cost includes obtaining a fresh buffer from the memory allocator and copying older characters into the new buffer, while CFA-sharing hides such a cost entirely.  The reuse-vs-fresh distinction is only relevant in the current \emph{append} tests.
     267These benchmark drivers have an outer loop for ``until a sample-worthy amount of execution has happened'' and an inner loop for ``build up the desired-length string.''  It is sensible to doubt that a user should have to care about this difference, yet the STL performs differently in these cases.  Concretely, both cases incur the cost of copying characters into the target string, but only the allocation-fresh case incurs a further reallocation cost, which is generally paid at points of doubling the length.  For the STL, this cost includes obtaining a fresh buffer from the memory allocator and copying older characters into the new buffer, while \CFA-sharing hides such a cost entirely.  The reuse-vs-fresh distinction is only relevant in the current \emph{append} tests.
    213268
    214269The \emph{append} tests use the varying-from-1 corpus construction; that is they do not assume away the STL's advantage from small-string optimization.
     
    230285\end{figure}
    231286
    232 In sharing mode, \CFA makes the fresh/reuse difference disappear, as shown in Figure \ref{fig:string-graph-peq-sharing}.  At append lengths 5 and above, CFA not only splits the two baseline STL cases, but its slowdown of 16\% over (STL with user-managed reuse) is close to the \CFA-v-STL implementation difference seen with \CFA in STL-emulation mode.
     287In sharing mode, \CFA makes the fresh/reuse difference disappear, as shown in Figure \ref{fig:string-graph-peq-sharing}.  At append lengths 5 and above, \CFA not only splits the two baseline STL cases, but its slowdown of 16\% over (STL with user-managed reuse) is close to the \CFA-v-STL implementation difference seen with \CFA in STL-emulation mode.
    233288
    234289\begin{figure}
     
    238293\end{figure}
    239294
    240 When the user takes a further step beyond the STL's optimal zone, by running @x = x + y@, as in Figure \ref{fig:string-graph-pta-sharing}, the STL's penalty is above $15 \times$ while CFA's (with sharing) is under $2 \times$, averaged across the cases shown here.  Moreover, the STL's gap increases with string size, while \CFA's converges.
     295When the user takes a further step beyond the STL's optimal zone, by running @x = x + y@, as in Figure \ref{fig:string-graph-pta-sharing}, the STL's penalty is above $15 \times$ while \CFA's (with sharing) is under $2 \times$, averaged across the cases shown here.  Moreover, the STL's gap increases with string size, while \CFA's converges.
    241296
    242297\subsubsection{Test: Pass argument}
     
    275330\begin{figure}
    276331    \includegraphics[width=\textwidth]{string-graph-allocn.png}
    277     \caption{Space and time performance, under varying fraction-live targets, for the five string lengths shown, at (\emph{Fixed-size} corpus construction.  [MISSING] The identified clusters are for the default fraction-live target, which is 30\%.  MISSING: STL results, typically just below the 0.5--0.9 CFA segment.  All runs keep an average of 836 strings live, and the median string lifetime is ?? allocations.}
     332    \caption{Space and time performance, under varying fraction-live targets, for the five string lengths shown, at (\emph{Fixed-size} corpus construction.  [MISSING] The identified clusters are for the default fraction-live target, which is 30\%.  MISSING: STL results, typically just below the 0.5--0.9 \CFA segment.  All runs keep an average of 836 strings live, and the median string lifetime is ?? allocations.}
    278333    \label{fig:string-graph-allocn}
    279334\end{figure}
     
    285340\subsubsection{Test: Normalize}
    286341
    287 This test is more applied than the earlier ones.  It combines the effects of several operations.  It also demonstrates a case of the CFA API allowing user code to perform well, while being written without overt memory management, while achieving similar performance in STL requires adding memory-management complexity.
     342This test is more applied than the earlier ones.  It combines the effects of several operations.  It also demonstrates a case of the \CFA API allowing user code to perform well, while being written without overt memory management, while achieving similar performance in STL requires adding memory-management complexity.
    288343
    289344To motivate: edits being rare
Note: See TracChangeset for help on using the changeset viewer.