Table Of ContentZU064-05-FPR arrowopt 3May2011 10:35
1
UnderconsiderationforpublicationinJ.FunctionalProgramming
Causal Commutative Arrows
HaiLiu∗,EricCheng†andPaulHudak
DepartmentofComputerScience
YaleUniversity
NewHaven,CT06520,U.S.A.
(e-mail:[email protected],[email protected],[email protected])
Abstract
Arrows are a popular form of abstract computation. Being more general than monads, they are
morebroadlyapplicable,andinparticularareagoodabstractionforsignalprocessinganddataflow
computations. Most notably, arrows form the basis for a domain specific language called Yampa,
which has been used in a variety of concrete applications, including animation, robotics, sound
synthesis,controlsystems,andgraphicaluserinterfaces.
Our primary interest is in better understanding the class of abstract computations captured by
Yampa. Unfortunately, arrows are not concrete enough to do this with precision. To remedy this
situationweintroducetheconceptofcommutativearrowsthatcaptureanon-interferenceproperty
of concurrent computations. We also add an init operator that captures the causal nature of arrow
effects,andidentifyitsassociatedlaw.
Tostudythisclassofcomputationsinmoredetail,wedefineanextensiontoarrowscalledcausal
commutativearrows(CCA),andstudyitsproperties.Ourkeycontributionistheidentificationofa
normalformforCCAcalledcausalcommutativenormalform(CCNF).Bydefininganormalization
procedurewehavedevelopedanoptimizationstrategythatyieldsdramaticimprovementsinperfor-
manceoverconventionalimplementationsofarrows.WehaveimplementedthistechniqueinHaskell,
andconductedbenchmarksthatvalidatetheeffectivenessofourapproach.Whencompiledwiththe
GlasgowHaskellCompiler(GHC),theoverallmethodologycanresultinsignificantspeed-ups.
1 Introduction
Considerthefollowingrecursivemathematicaldefinitionoftheexponentialfunction:
(cid:90)
t
e(t)=1+ e(t)dt
0
InYampa(Hudaketal.,2003),adomain-specificlanguageembeddedinHaskell(Peyton
Jonesetal.,2003),wecanwritethisusingarrowsyntax(Paterson,2001)asfollows:
exp=proc()→do
reclete=1+i
i←integral−≺e
returnA−≺e
∗ PresentlyatIntelLabs,IntelCorporation.
† PresentlyatGoogleInc.
ZU064-05-FPR arrowopt 3May2011 10:35
2 HaiLiu,EricChengandPaulHudak
EvenforthosenotfamiliarwitharrowsyntaxorHaskell,theclosecorrespondencebetween
themathematicsandtheYampaprogramshouldbeclear.Asinmosthigh-levellanguage
designs,thisistheprimarymotivationfordevelopingalanguagesuchasYampa:reducing
thegapbetweenprogramandspecification.
Yampahasbeenusedinavarietyofapplications,includingrobotics(Hudaketal.,2003;
Peterson et al., 1999a; Peterson et al., 1999b), sound synthesis (Giorgidze & Nilsson,
2008; Cheng & Hudak, 2009), animation (Hudak et al., 2003), video games (Courtney
etal.,2003;Cheong,2005),bio-chemicalprocesses(Hudaketal.,2008),controlsystems
(Oertel,2006),andgraphicaluserinterfaces(Courtney&Elliott,2001;Courtney,2004).
There are several reasons that we prefer a language design based on arrows over, for
example, an approach such as that used in Fran (Elliott & Hudak, 1997). First, arrows
are more direct – they convey information about input as well as output, whereas Fran’s
inputsareimplicitandglobal.Second,theuseofarrowseliminatesasubtlebutdevastating
formofspaceleak,asdescribedin(Liu&Hudak,2007).Third,arrowsintroduceameta-
levelofcomputationthataidsinreasoningaboutprogramcorrectness,transformation,and
optimization.
Butinfact,conventionalarrowsarenotstrongenoughtocapturethefamilyofcomputa-
tionsthatweareinterestedin–morelawsareneededtoconstrainthecomputationspace.
Unfortunately, more constrained forms of computation – such as monads (Moggi, 1991)
andapplicativefunctors(McBride&Paterson,2008)–arenotgeneralenough.Inaddition,
therearenotenoughoperators.Inparticular,wefindtheneedforanabstractinitialization
operatoranditsassociatedlaws.
In this paper we give a precise abstract characterization of a class of arrow computa-
tions that we call causal commutative arrows, or just CCA for short. More precisely, the
contributionsinthispapercanbesummarizedasfollows:
1. Wedefineanotionofcommutativearrowbyextendingtheconventionalsetofarrow
lawstoincludeacommutativitylaw.
2. WedefineanArrowInittypeclasswithaninitoperatorthatcapturestheessenceof
causalcomputationandsatisfiesaproductlaw.
3. WedefinearestrictedlanguagecalledCCA,inwhichtheaboveideasaremanifest.
Forsucharrowsweestablish:
(a) anormalform,and
(b) anormalizationprocedure.
We achieve this result using only CCA laws, without referring to any concrete se-
manticsorimplementation.
4. Wedefineanoptimizationtechniqueforcausalcommutativearrowsthatyieldssub-
stantialimprovementsinperformanceoverpreviousattemptstooptimizearrowcom-
binatorsandarrowsyntax.
5. Finally,weshowhowtoimplementourideasinGHCtoyieldspeed-ups,incertain
casesbyovertwoordersofmagnitude.
WebeginthepresentationwithabriefoverviewofarrowsinSection2.Theknowledge-
ablereadermayprefertoskipdirectlytoSection3,wherewegivethedefinitionandlaws
forCCA.InSection4weshowthatanyCCAprogramcanbetransformedintoauniform
representationthatwecallCausalCommutativeNormalForm(CCNF).Weprovethatthe
ZU064-05-FPR arrowopt 3May2011 10:35
JournalofFunctionalProgramming 3
normalizationprocedureissound,basedonequationalreasoningusingonlytheCCAlaws.
In Section 5 we discuss further optimizations, and in Section 6 their implementations in
GHC.WepresentsomebenchmarksshowingtheeffectivenessofourapproachinSection
7.WediscussinSection8possibleextensions,andinSection9relatedwork.
2 AnIntroductiontoArrows
Arrows (Hughes, 2000) are a generalization of monads that relax the stringent linearity
imposedby monads,while retaininga disciplined styleof composition. Arrowshaveen-
joyedawiderangeofapplications,oftenasadomain-specificembeddedlanguage(DSEL
(Hudak,1996;Hudak,1998)),includingthemanyYampaapplicationscitedearlier,aswell
asparsersandprinters(Jansson&Jeuring,1999),parallelcomputing(Huangetal.,2007),
and so on. Arrows also have a theoretical foundation in category theory, where they are
stronglyrelatedto(butnotpreciselythesameas)Freydcategories(Atkey,2008;Power&
Thielecke,1999).
2.1 ConventionalArrows
Like monads, arrows capture a certain class of abstract computations, and offer a way to
structureprograms.InHaskellthisisachievedthroughtheArrowtypeclass:
classArrowawhere
arr ::(b→c)→abc
(≫)::abc→acd→abd
first ::abc→a(b,d)(c,d)
Thecombinatorarrliftsafunctionfrombtoctoa“pure”arrowcomputationfrombtoc,
namelyabcwhereaisthearrowtype.Theoutputofapurearrowentirelydependsonthe
input(itisanalogoustoreturnintheMonadclass).≫composestwoarrowcomputations
by connecting the output of the first to the input of the second (and is analogous to bind
>>= in the Monad class). But in addition to composing arrows linearly, it is desirable to
composetheminparallel–i.e.toallow“branching”and“merging”ofinputsandoutputs.
Thereareseveralwaystodothis,butbysimplydefiningthefirstcombinatorintheArrow
class,allothercombinatorscanbedefined.firstconvertsanarrowcomputationtakingone
input and one result, into an arrow computation taking two inputs and two results. The
originalarrowisappliedtothefirstpartoftheinput,andtheresultbecomesthefirstpart
oftheoutput.Thesecondpartoftheinputisfeddirectlytothesecondpartoftheoutput.
Othercombinatorscanbedefinedusingthesethreeprimitives.Forexample,thedualof
firstcanbedefinedas:
second ::(Arrowa)⇒abc→a(d,b)(d,c)
secondf =arrswap≫firstf ≫arrswap
whereswap(a,b)=(b,a)
Parallelcompositioncanbedefinedasasequenceoffirstandsecond:
(???) ::(Arrowa)⇒abc→ab0c0→a(b,b0)(c,c0)
f???g=firstf ≫secondg
ZU064-05-FPR arrowopt 3May2011 10:35
4 HaiLiu,EricChengandPaulHudak
leftidentity arrid≫f =f
rightidentity f ≫arrid=f
associativity (f ≫g)≫h=f ≫(g≫h)
composition arr(g.f)=arrf ≫arrg
extension first(arrf)=arr(f×id)
functor first(f ≫g)=firstf ≫firstg
exchange firstf ≫arr(id×g)=arr(id×g)≫firstf
unit firstf ≫arrfst=arrfst≫f
association first(firstf)≫arrassoc=arrassoc≫firstf
whereassoc((a,b),c)=(a,(b,c))
Fig.1. Conventionalarrowlaws
lefttightening loop(firsth≫f)=h≫loopf
righttightening loop(f ≫firsth)=loopf ≫h
sliding loop(f ≫arr(id×k))=loop(arr(id×k)≫f)
vanishing loop(loopf)=loop(arrassoc−1≫f ≫arrassoc)
superposing second(loopf)=loop(arrassoc≫secondf ≫arrassoc−1)
extension loop(arrf)=arr(tracef)
wheretracef b=let(c,d)=f (b,d)inc
Fig.2. Arrowlooplaws
Amereimplementationofthearrowcombinators,ofcourse,doesnotmakeitanarrow
–itmustadditionallysatisfyasetofarrowlaws,whichareshowninFigure1.
2.2 LoopingArrows
Tomodelrecursion,wecanintroducealoopcombinator(Paterson,2001).Theexponential
example given in the introduction requires recursion, as do many applications in signal
processing,forexample.InHaskellthiscombinatoriscapturedintheArrowLoopclass:
classArrowa⇒ArrowLoopawhere
loop::a(b,d)(c,d)→abc
A valid instance of this class should satisfy the additional laws shown in Figure 2. This
classanditsassociatedlawsarerelatedtothetraceoperatorin(Streetetal.,1996;Hasegawa,
1997),whichwasgeneralizedtoarrowsin(Paterson,2001).
Wefindthatarrowsarebestviewedpictorially,especiallyforapplicationssuchassignal
processing,wheredomainexpertscommonlydrawsignalflowdiagrams.Figure3shows
someofthebasiccombinatorsinthismanner,includingloop.
2.3 ArrowSyntax
RecalltheYampadefinitionoftheexponentialfunctiongivenearlier:
exp=proc()→do
reclete=1+i
i←integral−≺e
returnA−≺e
ZU064-05-FPR arrowopt 3May2011 10:35
JournalofFunctionalProgramming 5
arr ::Arrowa⇒(b→c)→abc
(≫)::Arrowa⇒abc→acd→abd
first ::Arrowa⇒abc→a(b,d)(c,d)
(???)::Arrowa⇒abc→ab0c0→a(b,b0)(c,c0)
loop ::Arrowa⇒a(b,d)(c,d)→abc
(a) arrf (b) f≫g (c) firstf
(d) f???g (e) loopf
Fig.3. CommonlyUsedArrowCombinators
commutativityfirstf ≫secondg=secondg≫firstf
product initi???initj=init(i,j)
Fig.4. CausalCommutativeArrowLaws
This program is written using arrow syntax, introduced by (Paterson, 2001) and adopted
by GHC (the predominant Haskell implementation) because it ameliorates the cumber-
somenatureofwritinginthepoint-freestyledemandedbyarrowcombinators.Theabove
programisequivalenttothefollowingsugar-freeprogram:
exp=fixA(integral≫arr(+1))
wherefixAf =loop(secondf ≫arr(dup.snd))
dupx=(x,x)
Althoughmorecumbersome,wewillusethisprogramstyleintheremainderofthepaper,
inordertoavoidhavingtoexplainthemeaningofarrowsyntaxinmoredetail.
3 CausalCommutativeArrows
In this section we introduce two key extensions to conventional arrows, and demonstrate
theirusebyimplementingastreamtransformerinHaskell.
First, as mentioned in the introduction, the set of arrow and arrow loop laws is not
strongenoughtocapturestreamcomputations.Inparticular,thecommutativitylawshown
in Figure 4 establishes a non-interference property for concurrent computations – effects
arestillallowed,butthislawguaranteesthatconcurrenteffectscannotinterferewitheach
other.Wesaythatanarrowiscommutativeifitsatisfiestheconventionallawsaswellas
thiscriticaladditionallaw.Yampaisinfactbasedoncommutativearrows.
Second, we note that Yampa has a primitive operator called iPre that is used to inject
a delay into a computation; indeed it is the primary effect imposed by the Yampa arrow
(Hudak et al., 2003). Similar operators, often called delay, also appear in dataflow pro-
ZU064-05-FPR arrowopt 3May2011 10:35
6 HaiLiu,EricChengandPaulHudak
newtypeSFab=SF{unSF::a→(b,SFab)}
instanceArrowSFwhere
arrf =SFh wherehx =(f x,SFh)
firstf =SF(hf) wherehf (x,z) =let(y,f0)=unSFf x
in((y,z),SF(hf0))
f ≫g=SF(hf g)wherehf gx =let(y,f0)=unSFf x
(z,g0)=unSFgy
in(z,SF(hf0g0))
instanceArrowLoopSFwhere
loopf =SF(hf) wherehf x =let((y,z),f0)=unSFf (x,z)
in(y,SF(hf0))
instanceArrowInitSFwhere
initi=SF(hi) wherehix =(i,SF(hx))
run ::SFab→[a]→[b]
sf
run f =gf wheregf (x:xs)=let(y,f0)=unSFf x
sf
iny:gf0xs
Fig.5. CausalStreamTransformer
gramming (Wadge & Ashcroft, 1985), stream processing (Stephens, 1997; Thies et al.,
2002), and synchronous languages (Caspi et al., 1987; Colac¸o et al., 2004). In all cases,
theoperatorintroducesstatefulcomputationintoanotherwisestatelesssetting.
Inanefforttomakethisoperationmoreabstract,werenameitinitandcaptureitinthe
followingtypeclass:
classArrowLoopa⇒ArrowInitawhere
init::b→abb
Intuitively,theargumenttoinitistheinitialoutput;subsequentoutputisacopyoftheinput
tothearrow.Itcapturestheessenceofcausalcomputations,namelythatthecurrentoutput
dependsonlyonthecurrentaswellaspreviousinputs.Besidescausality,wemakenoother
assumptionsaboutthenatureofthesevalues:theymayormaynotvarywithtime,andthe
incrementofchangemaybefiniteorinfinitesimallysmall.
More importantly, a valid instance of the ArrowInit class must satisfy the product law
showninFigure4.Thislawstatesthattwoinitspairedtogetherareequivalenttooneinitof
apair.Hereweusethe???operatorinsteadofitsexpandeddefinitionfirst...≫second...
toimplythattheproductlawassumescommutativity.
Wewillseeinalatersectionthatinitandtheproductlawarecriticaltoournormalization
andoptimizationstrategies.Butinitisalsoimportantinallowingustodefineoperatorsthat
were previously taken as domain-specific primitives. In particular, consider the integral
operatorusedintheexponentiationexamples.Withinit,wecandefineintegralusingthe
Eulerintegrationmethodandafixedglobalstepdtasfollows:
integral :: ArrowInita⇒aDoubleDouble
integral=loop(arracc≫init0≫arrdup)whereacc(x,i)=i+dt∗x
dupx=(x,x)
To complete the picture, we give an instance (i.e. an implementation) of CCA that
capturesacausalstreamtransformer,asshowninFigure5,where:
ZU064-05-FPR arrowopt 3May2011 10:35
JournalofFunctionalProgramming 7
• SF a b is an arrow representing functions (transformers) from streams of type a
to streams of type b. It is essentially a recursively defined data type consisting of
a function with its continuation, a concept closely related to a form of finite state
automatoncalledaMealyMachine(G.H.Mealy,1955).Yampaemploysasimilar
implementation,andthesamedatatypewascalledAutoin(Paterson,2001).
• SF is declared an instance of type classes Arrow, ArrowLoop and ArrowInit. For
example, exp can be instantiated as type exp::SF()Double. These instances obey
allofthearrowlaws,includingthetwoadditionallawsthatweintroduced.
• run ::SFab→[a]→[b]convertsanSFarrowintoastreamtransformerthatmaps
sf
aninputstreamoftype[a]toanoutputstreamoftype[b].
Asademonstration,wecansampletheexponentialfunctionatafixedtimeintervalby
runningtheexparrowoveranuniforminputstreaminp:
dt =0.01 ::Double
inp=():inp ::[()]
∗Main>run expinp
sf
[1.0,1.01,1.0201,1.030301,1.04060401,1.0510100501,...
We must stress that the SF type is but one instance of a causal commutative arrow, and
alternative implementations such as the synchronous circuit type SeqMap in (Paterson,
2001) and the stream function type (incidentally also called) SF in (Hughes, 2004) also
qualify as valid instances. The abstract properties such as normal forms that we develop
in the next section are applicable to any of these instances, and thus are more broadly
applicable than optimization techniques based on a specific semantic model, such as the
oneconsideredin(Caspi&Pouzet,1998).
4 NormalizationofCCA
In most implementations, arrow programs carry a run-time overhead, primarily due to
the use of a data structure for arrow instances, as well as the extra tupling forced onto
function’sargumentsandreturnvalues.Therehavebeenseveralattempts(Hughes,2004;
Nilsson,2005)tooptimizearrow-basedprogramsusingarrowlaws,buttheresulthasnot
beenentirelysatisfactory.Althoughconventionalarrowandarrowlooplawsofferwaysto
combine pure arrows and collapse nested loops, they are not specific enough to target
effectful arrows, such as the init combinator. Certain effectful arrows are dynamically
optimizedin(Nilsson,2005),buttheyarebasedonsomewhatad-hoclaws,andthereare
nonormalforms.
Ournewstrategyisbasedonthefollowingratherstrikingobservation:anyCCAprogram
canbetransformedintoasingleloopcontainingonepurearrowandoneinitialstatevalue.
Moreprecisely,anyCCAprogramcanbenormalizedintoeithertheformarrf or:
loop(arrf ≫second(initi))
where f is a pure function and i is an initial state. Note that all the essential arrow com-
binators, arr, ≫, second, loop and init, are used exactly once, and therefore all of the
overheads (tupling, etc.) associated with multiple occurrences and compositions of the
ZU064-05-FPR arrowopt 3May2011 10:35
8 HaiLiu,EricChengandPaulHudak
Fig.6. DiagramforloopD
(a) Original (b) Optimized
Fig.7. Diagramsforexp
arrowcombinatorsarecompletelyeliminated.Notsurprisingly,theresultingimprovement
inperformanceisratherdramatic,aswewillseelater.
FirstwedefineacombinatorcalledloopDthatcanbeviewedassyntacticsugarforthe
aboveform:
loopD :: ArrowInita⇒d→((b,d)→(c,d))→abc
loopDif =loop(f ≫second(initi))
A pictorial view of loopD is given in Figure 6. The second argument to loopD is a pure
functionmappingatupleof(b,d)to(c,d),wherethevalueoftyped isinitializedbefore
loopingback,andisoftenregardedasaninternalstate.
Asaconcreteexample,Figure7(a)isadiagramoftheoriginalexpexamplegivenearlier.
In Figure 7(b) we have inlined the definition of integral and applied the optimization
strategy. The result is a single loop, where all pure functions can be combined together
tominimizearrowimplementationoverheads.
Tobemorepreciseastowhatkindofarrowsaresubjecttonormalization,wewantto
restrictourdiscussioninthissectiononwell-formedandclosedCCAterms.
Definition4.1(CCA)
Acausalcommutativearrow(CCA)isavalidinstanceoftheArrowInitclass,whoseterms
aredefinablefromonlythefollowingcombinators:arr,first,≫,loopandinit.AllCCAs
mustsatisfythetwoCCAlawsgiveninFigure4inadditiontothearrowandarrowloop
laws.
Definition4.1effectivelymeans:
1. WeareonlyconcernedwithCCAswritteninclosedterms,withoutreferencingarrow
definitionsfromtheenvironment(syntacticsugarisstillallowed).
2. Sucharrowsmustnotberecursivelydefinedotherwisenormalizationwouldfailto
terminate.
3. Thereisnolambdaabstractionorapplicationatthearrowlevelsothatwecanavoid
talkingaboutbetareductionorvariablesubstitutionofarrowterms.Note,however,
thatwedoallowallformsoffunctions,includingrecursiveones,tobeliftedbyarr.
Definition4.1mayseemtoorestrictiveasitprecludesanyformofmodularityforCCA
sincealltermsareclosed.Webelievethisisonlyanecessarysteptoavoidcomplicationsin
formalizingCCAproperties,andcancertainlyberelaxedinreal-worldimplementations.
ZU064-05-FPR arrowopt 3May2011 10:35
JournalofFunctionalProgramming 9
composition arrf ≫arrg7→arr(g.f)
lefttightening arrf ≫loopDig7→loopDi(g.(f×id))
righttightening loopDif ≫arrg7→loopDi((g×id).f)
sequencing loopDif ≫loopDjg7→loopD(i,j)(assoc0(juggle0(g×id).(f×id)))
extension first(arrf)7→arr(f×id)
superposing first(loopDif)7→loopDi(juggle0(f×id))
loop-extension loop(arrf)7→arr(tracef)
vanishing loop(loopDif)7→loopDi(trace(juggle0f))
f×g(x,y)=(f x,gy) swap(x,y)=(y,x)
assoc ((x,y),z)=(x,(y,z)) tracef x=let(y,z)=f (x,z)iny
assoc−1(x,(y,z))=((x,y),z) juggle((x,y),z)=((x,z),y)
assoc0f =assoc.f .assoc−1 juggle0f =juggle.f .juggle
Fig.8. SingleStepReductionforCCA
(NORM1) (NORM2)
arr f ⇓arr f loopDi f ⇓loopDi f
e ⇓e0 e ⇓e0 e0 ≫e0 7→e
1 1 2 2 1 2
(INIT) (SEQ)
initi⇓loopDiswap e ≫e ⇓e
1 2
f ⇓ f0 first f07→e f ⇓ f0 loop f07→e
(FIRST) (LOOP)
first f ⇓e loop f ⇓e
Fig.9. NormalizationofCCA
OurintuitionbehindthenormalizationprocessistoextendarrowlooplawstoloopD,so
that we only get the loopD form as a result. Formally we define a single step reduction
7→ for CCA as a set of rules in Figure 8, and a normalization procedure in Figure 9.
The normalization relation ⇓ can be seen as a big step reduction following an innermost
strategy,andisindeedafunction.
Notethatsomeofthereductionrulesresemblethearrowlawsofthesamename.How-
ever, there are some subtle but important differences: First, unlike the laws, reduction is
directed.Second,therulesareextendedtohandleloopDinsteadofloop.
Toseehowthisworks,itishelpfultovisualizeafewexamplesofthereductionrulesin
Figure 8, as shown in Figure 10. We omit the simpler rules that follow directly from the
laws,andonlyshowthosethatinvolveloopD.ThediagramsinFigure10canbeexplained
asfollows:
(a) lefttightening. Figure 10(a) shows that we can move a pure arrow from a left
compositioninsidealoopDarrow.Thisfollowsdirectlyfromthelefttighteninglaw
ofloop.
(b) righttightening. Figure 10(b) shows that we can move a pure arrow from a right
composition inside a loopD arrow so that it fuses with the pure function inside the
loopD.Thisfollowsdirectlyfromthelefttighteninglawofloopandthecommuta-
tivitylawofCCA.
ZU064-05-FPR arrowopt 3May2011 10:35
10 HaiLiu,EricChengandPaulHudak
(a) lefttightening (b) righttightening (c) sequencing
(d) superposing (e) vanishing
Fig.10. IllustrationsofReductionRules
(c) sequencing. Figure 10(c) shows that we can combine two loopD arrows into one.
In doing so, we have to re-route part of the computation, and make use of product
lawtofusetwoinitarrowsintoone.Noticethatthereisalsoare-orderingofapure
arrowandaninitarrow,whichisduetothecommutativitylawofCCA.
(d) superposing.Figure10(d)showsavariantofthesuperposinglawforloopDusing
first instead of second. Instead of an outer parallel composition, the second line
simplypassesthroughtheloopDunchangedwithsomere-routing.
(f) vanishing.Figure10(e)showsanextensionofthevanishinglawforloopstohandle
loopD. Since the outer loop only acts on the pure function, it can be moved inside
andcomposedwiththetracefunctionduetotheloopextensionlaw.
Lemma4.1(Soundness)
ThereductionrulesgiveninFigure8arebothtypeandsemanticspreserving,i.e.,ife7→e0
thene=e0issyntacticallyderivablefromthesetofCCAlaws.
Proof:Byequationalreasoningusingarrowlaws.Thecomposition,extensionandloop-
extension reduction rules are directly based on the arrow laws with the same name; left
andrighttightening,superposingandvanishingreductionrulesfollowthedefinitionof
loopD,thecommutativitylawandthearrowlooplawswiththesamename.Theproofof
thesequencingruleismoreinvolved,andisgiveninAppendixB. (cid:164)
Lemma4.2(Termination)
ThenormalizationprocedureforCCAgiveninFigure9terminatesforallCCAs.
Proof: By structural induction over all possible definitions of a CCA program. The rules
NORM1, NORM2, and INIT are the base case, and SEQ, FIRST, and LOOP cover the
inductive case, where the sub arrows (such as e and e in e ≫e , and f in firstf and
1 2 1 2
loopf)arenormalizedinductively.Italsoexplainswhythereareexactly8reductionrules
Description:May 3, 2011 Under consideration for publication in J. Functional Programming. 1. Causal Commutative Arrows. Hai Liu∗, Eric Cheng† and Paul Hudak.