module Clipboard sig Text {} sig Editor { text: set Text, selection: option Text, clipboard: option Text }{ selection in text } fun Same (ed1,ed2: Editor) { ed1.text = ed2.text && ed1.selection = ed2.selection && ed1.clipboard = ed2.clipboard } fun Select (ed,ed': Editor) { ed'.text = ed.text some t: ed.text | ed'.selection = t ed'.clipboard = ed.clipboard } fun Copy (ed,ed': Editor) { ed'.text = ed.text ed'.selection = ed.selection ed'.clipboard = if some ed.selection then ed.selection else ed.clipboard } fun Cut (ed,ed': Editor) { no ed.selection => ed' = ed, // otherwise (ed'.text = ed.text - ed.selection && ed'.selection = none[Text] && ed'.clipboard = ed.selection) } fun Paste (ed,ed': Editor) { no ed.clipboard => ed' = ed, // otherwise (ed'.text = ed.text + ed.clipboard && ed'.selection = none[Text] && ed'.clipboard = ed.clipboard) } assert SelectionDoesNotAffectText { all ed0,ed1: Editor | Select(ed0,ed1) => ed0.text = ed1.text } assert CutThenPasteGivesSameText { all ed0,ed1,ed2,ed3:Editor | Select(ed0,ed1) && Cut(ed1,ed2) && Paste(ed2,ed3) => ed1.text = ed3.text } assert CopyPlusCutEqualsCut { all ed0,ed1,ed2,ed3,ed4: Editor | Select(ed0,ed1) && Copy(ed1,ed2) && Cut(ed2,ed3) && Cut(ed1,ed4) => Same(ed3,ed4) } check SelectionDoesNotAffectText for 2 Editor, 2 Text check CutThenPasteGivesSameText for 4 Editor, 2 Text check CopyPlusCutEqualsCut for 5 Editor, 2 Text