'From Squeak2.7 of 5 January 2000 [latest update: #1782] on 3 September 2000 at 11:34:39 am'! Object subclass: #Couplet instanceVariableNames: 'id1 id2 ' classVariableNames: '' poolDictionaries: '' category: 'Quarks-Basics'! Couplet class instanceVariableNames: ''! Object subclass: #Qid instanceVariableNames: 'literal token ' classVariableNames: '' poolDictionaries: '' category: 'Quarks-Basics'! Object subclass: #QuarkSpace instanceVariableNames: 'space tokensToIds stringsToIds ' classVariableNames: 'CharacterSets DiscardableTriggers LineBreaks StateMachine Transitions ' poolDictionaries: '' category: 'Quarks-Basics'! QuarkSpace class instanceVariableNames: ''! Object subclass: #State instanceVariableNames: 'triggers transitions ' classVariableNames: '' poolDictionaries: '' category: 'Quarks-Basics'! Object subclass: #StringComposer instanceVariableNames: 'type pattern ' classVariableNames: '' poolDictionaries: '' category: 'Quarks-Basics'! Object subclass: #StringQuery instanceVariableNames: 'isCaseSensitive isPartial byWord delimiters usesRegEx booleanFunction values ' classVariableNames: '' poolDictionaries: '' category: 'Quarks-Basics'! Object subclass: #Transition instanceVariableNames: 'targetState action ' classVariableNames: '' poolDictionaries: '' category: 'Quarks-Basics'! Object subclass: #Triplet instanceVariableNames: 'id1 id2 id3 ' classVariableNames: '' poolDictionaries: '' category: 'Quarks-Basics'! Triplet class instanceVariableNames: ''! !Object methodsFor: 'testing' stamp: 'cf 9/2/2000 16:58'! isSequenceable ^ false! ! !Object methodsFor: 'testing' stamp: 'cf 9/2/2000 13:52'! isString ^ false! ! !Object methodsFor: 'testing' stamp: 'cf 9/2/2000 13:52'! isSymbol ^ false! ! !Couplet commentStamp: '' prior: 0! "Mannby" "Fred" "Claes-Fredrik" "425 556 3038" XML: : "Mannby" : "Fred" ... "Model Name" "Package Name" "Classifier Name" "Attribute Name" "Model Name" "Package Name" a is the b c d "X is the best blue book in the store." search: * after: * View: "View1" ", " O Create module to hold triplets of 8-byte ids O Create map between identifiers and ids O Create xml-triplet converter (to identifiers) O Create triplet (identifiers) to triplets (ids) converter O Define basic ids and identifiers, such as the ones used here O Create query function into id module O Write demo app that extracts a view and applies it to applicable entries O Create a hold-anything data structure Hold-anything-data-structure (HAD) 0->0 -1->254+more rest->length (in file) (in memory, use different size storing mechanism) Key principles: a) Structure lies primarily in the view quarks, not in the model quarks. b) The model quarks are exactly specific quarks floating in the "plasma," with little or no structure. a) The "metamodels" lie in the views. I.e., relationships related to classes of quarks are view artifacts. b) Relationships specific to instances are model artifacts. 1) Creation of quarks will generally happen by applying a view to some data to generate quarks. #(define contact (view (name* address* phone* data*)) (define name (view (expression (firstName middleInitial LastName))) (define namePart (model (tag value))) (define name (model (namePart*))) ) (quark 1 string Claes-Fredrik) (quark 2 string Urban) (quark 3 string Mannby) (quark 4 string "(425) 556 3038") (quark a string "First Name") (quark b string "Claes-Fredrik") (quark c string "Last Name") (quark d string "Mannby") (quark 5 assoc a b) (quark 6 assoc c d) (quark x group 5 6) (quark y assoc (quark contact) (quark x)) Couplet from: #quark and: #quark #((define string String) (define number Number) (define integer Integer) (subtype number integer) (subtype number real) (define real Real) (subtype string firstName) (subtype string lastName) (subtype string middleName) (define simpleName (firstname middleName lastName)) (define phoneType string) (define phoneNumber integer) (define phone (phoneType phoneNumber)) (define contact (name address phone*)) (define ) Claes-Fredrik Mannby USA (425) 392 6502 (425) 556 3038
Home 4334 252nd Pl. SE Issaquah, WA 98028
Sweden MossvŠgen 48 S-14144 HUDDINGE Sweden
Plan of attack: 1) Allow the definition of a view metamodel for a certain type of data. 2) Generate "view" and "model" metadata in quark space. 3) Allow custom code to augment the tranlations between view and model (both ways). 4) Have predefined, and allow definition of more, types, especially parsers for phone numbers, country and city enumerations, etc. 5) Must be able to handle: a) A person being in different places over time, perhaps computed by an algorithm, or according to a schedule. b) A person having different information about him in different locations (i.e. contexts). E.g. address of person x in Sweden is either a, b or c (b in even years). c) Different parsing of phone numbers according to their locale (without having to specify the locale of each phone number explicitly). c2) This is analogous to generating and parsing different code in different languages for the same operation. 1) Design a database that is metamodel-agnostic, i.e., with a generic metamodel that support any metamodel. 2) Design a metamodel that is able to grow over time. It should allow for as much reuse as possible, and for easy extension of existing "schema," conforming to a meta-schema rather than more narrow domain-schemas. I think was this will mean is that it should support the basic categories of human classification, including Aristotle's categories, logic, computational basics, and little else.! !Couplet methodsFor: 'accessing' stamp: 'cf 3/26/2000 17:56'! id1: anId1 id1 _ anId1.! ! !Couplet methodsFor: 'accessing' stamp: 'cf 3/26/2000 17:55'! id1: anId1 id2: anId2 id1 _ anId1. id2 _ anId2.! ! !Couplet methodsFor: 'accessing' stamp: 'cf 3/26/2000 17:56'! id2: anId2 id2 _ anId2.! ! !Couplet class methodsFor: 'instance creation' stamp: 'cf 3/26/2000 17:55'! from: anId1 and: anId2 | answer | answer _ self new. answer id1: anId1 id2: anId2. ^ answer! ! !Qid methodsFor: 'printing' stamp: 'cf 8/31/2000 21:58'! printOn: aStream literal isNil ifTrue: [aStream nextPut: $<; nextPutAll: token; nextPut: $>] ifFalse: [aStream nextPut: $"; nextPutAll: literal; nextPut: $"]! ! !Qid methodsFor: 'accessing' stamp: 'cf 8/17/2000 13:55'! literal: aLiteral literal _ aLiteral. token _ nil! ! !Qid methodsFor: 'accessing' stamp: 'cf 8/17/2000 13:55'! token: aToken token _ aToken. literal _ nil! ! !Qid class methodsFor: 'instance creation' stamp: 'cf 8/31/2000 21:40'! fromLiteral: aLiteral ^ self new literal: aLiteral! ! !Qid class methodsFor: 'instance creation' stamp: 'cf 8/31/2000 21:40'! fromToken: aToken ^ self new token: aToken! ! !QuarkSpace reorganize! ('initializing' initialize) ('private' triggerFromCharacter:amongTriggers:) ('accessing' addTriplet: numberToId: stringToId: tokenToId:) ('parsing-tabbed' collectQuarksForHeader:signature:tokenComposer: collectTabDelimitedCellsInLine: parseTabDelimitedLine:number:signature:attributes:entityComposer: parseTabDelimitedTableWithHeaderStream:withSignature:) ('parsing-basic' parseLine: parseStream:) ('searching' collectq1Withq2:q3: collectq3Withq1:q2: q1Withq2:q3: q3Withq1:q2:) ! !QuarkSpace methodsFor: 'initializing' stamp: 'cf 9/1/2000 21:47'! initialize space _ Set new. tokensToIds _ IdentityDictionary new. stringsToIds _ Dictionary new.! ! !QuarkSpace methodsFor: 'private' stamp: 'cf 8/31/2000 20:52'! triggerFromCharacter: aChar amongTriggers: triggers triggers do: [:eachTrigger | ((CharacterSets at: eachTrigger) includes: aChar) ifTrue: [^ eachTrigger]]. ^ nil! ! !QuarkSpace methodsFor: 'accessing' stamp: 'cf 9/1/2000 21:47'! addTriplet: aTriplet space add: aTriplet.! ! !QuarkSpace methodsFor: 'accessing' stamp: 'cf 8/31/2000 21:47'! numberToId: aString ^ stringsToIds at: aString ifAbsentPut: [Qid fromLiteral: aString]! ! !QuarkSpace methodsFor: 'accessing' stamp: 'cf 8/17/2000 14:03'! stringToId: aString ^ stringsToIds at: aString ifAbsentPut: [Qid fromLiteral: aString]! ! !QuarkSpace methodsFor: 'accessing' stamp: 'cf 9/1/2000 21:27'! tokenToId: aString ^ tokensToIds at: aString asSymbol ifAbsentPut: [Qid fromToken: aString]! ! !QuarkSpace methodsFor: 'parsing-tabbed' stamp: 'cf 9/2/2000 17:23'! collectQuarksForHeader: aHeader signature: aSignature tokenComposer: aTokenComposer "Answer a collection of ids, one for each column." ^ aHeader collect: [:eachColumn | eachColumn isEmpty ifTrue: [nil] ifFalse: [self tokenToId: (aTokenComposer composeWith: (OrderedCollection with: aSignature with: eachColumn))]]! ! !QuarkSpace methodsFor: 'parsing-tabbed' stamp: 'cf 9/2/2000 17:11'! collectTabDelimitedCellsInLine: aStream "Answer a collection of strings, one for each column/cell." | eachChar tab eachName answer | answer _ OrderedCollection new. tab _ Character tab. eachName _ ReadWriteStream on: (String new: 100). [aStream atEnd] whileFalse: [eachChar _ aStream next. eachChar == tab ifTrue: [answer add: eachName contents. eachName _ ReadWriteStream on: (String new: 100)] ifFalse: [eachName nextPut: eachChar]]. ^ answer! ! !QuarkSpace methodsFor: 'parsing-tabbed' stamp: 'cf 9/2/2000 17:38'! parseTabDelimitedLine: aStream number: aLineNum signature: aSignature attributes: attributes entityComposer: aTokenComposer "Extract a triplet about the entity described in this line for each cell." | cells entityId isBlank cellIds | cells _ self collectTabDelimitedCellsInLine: aStream. isBlank _ true. cellIds _ cells collect: [:eachCell | eachCell isEmpty ifTrue: [nil] ifFalse: [isBlank _ false. self stringToId: eachCell]]. isBlank ifTrue: [^ self]. entityId _ aTokenComposer composeWith: (OrderedCollection with: cells with: aSignature with: aLineNum). cellIds doWithIndex: [:eachId :index | eachId isNil ifFalse: [self addTriplet: (Triplet id1: eachId id2: (attributes at: index) id3: entityId)]]! ! !QuarkSpace methodsFor: 'parsing-tabbed' stamp: 'cf 9/2/2000 17:52'! parseTabDelimitedTableWithHeaderStream: aStream withSignature: aSignature | eachChar eachLine lineNum header attributes attributeTypeComposer entityComposer firstNameQuery lastNameQuery | lineNum _ 0. header _ nil. attributeTypeComposer _ StringComposer pattern: {#simple. 'is-'. 1. '-'. 2. '-of'}. entityComposer _ StringComposer pattern: {#or. {#allRequired. 2. '-'. {1. #hole}. ' '. {1. #hole}}. {#simple. 2. '-line-'. 3}}. firstNameQuery _ StringQuery with: {#and. 'first'. 'name'}. lastNameQuery _ StringQuery with: {#and. 'last'. 'name'}. eachLine _ ReadWriteStream on: (String new: 1000). [aStream atEnd] whileFalse: [eachChar _ aStream next. (LineBreaks includes: eachChar) ifTrue: [eachLine position > 0 ifTrue: [lineNum _ lineNum + 1. "Add a tab, so we don't need to special case EOL." eachLine nextPut: Character tab. eachLine position: 0. header isNil ifTrue: [header _ self collectTabDelimitedCellsInLine: eachLine. attributes _ self collectQuarksForHeader: header signature: aSignature tokenComposer: attributeTypeComposer. entityComposer completeWith: (Array with: (firstNameQuery indexInCollection: header) with: (lastNameQuery indexInCollection: header))] ifFalse: [self parseTabDelimitedLine: eachLine number: lineNum signature: aSignature attributes: attributes entityComposer: entityComposer]. eachLine _ ReadWriteStream on: (String new: 1000)]] ifFalse: [eachLine nextPut: eachChar]]! ! !QuarkSpace methodsFor: 'parsing-basic' stamp: 'cf 9/1/2000 21:45'! parseLine: aStream | stateSymbol state eachChar eachQuark eachTrigger position newTriplet transition | stateSymbol _ #outside. state _ StateMachine at: stateSymbol. newTriplet _ Triplet new. position _ 0. eachQuark _ nil. [aStream atEnd] whileFalse: [eachChar _ aStream next. eachTrigger _ self triggerFromCharacter: eachChar amongTriggers: state triggers. eachTrigger isNil ifTrue: [stateSymbol ~~ #outside ifTrue: [eachQuark nextPut: eachChar]] ifFalse: [stateSymbol == #outside ifTrue: [eachQuark _ ReadWriteStream on: (String new: 200)]. (DiscardableTriggers includes: eachTrigger) ifFalse: [eachQuark nextPut: eachChar]. transition _ state transitions at: eachTrigger. transition action isNil ifFalse: [position _ position + 1. newTriplet at: position put: (self perform: transition action with: eachQuark contents).]. stateSymbol _ transition targetState. state _ StateMachine at: stateSymbol.]]. position = 3 ifTrue: [self addTriplet: newTriplet]! ! !QuarkSpace methodsFor: 'parsing-basic' stamp: 'cf 9/1/2000 22:18'! parseStream: aStream | eachChar eachLine | eachLine _ ReadWriteStream on: (String new: 500). [aStream atEnd] whileFalse: [eachChar _ aStream next. (LineBreaks includes: eachChar) ifTrue: [eachLine position > 0 ifTrue: [eachLine position: 0. self parseLine: eachLine. eachLine _ ReadWriteStream on: (String new: 500)]] ifFalse: [eachLine nextPut: eachChar]]! ! !QuarkSpace methodsFor: 'searching' stamp: 'cf 9/2/2000 18:53'! collectq1Withq2: q2 q3: q3 | answer | answer _ IdentitySet new. space do: [:eachTriplet | (eachTriplet id2 == q2 and: [eachTriplet id3 == q3]) ifTrue: [answer add: eachTriplet id1]]. ^ answer! ! !QuarkSpace methodsFor: 'searching' stamp: 'cf 9/2/2000 18:55'! collectq3Withq1: q1 q2: q2 | answer | answer _ IdentitySet new. space do: [:eachTriplet | (eachTriplet id1 == q1 and: [eachTriplet id2 == q2]) ifTrue: [answer add: eachTriplet id3]]. ^ answer! ! !QuarkSpace methodsFor: 'searching' stamp: 'cf 9/2/2000 18:53'! q1Withq2: q2 q3: q3 space do: [:eachTriplet | (eachTriplet id2 == q2 and: [eachTriplet id3 == q3]) ifTrue: [^ eachTriplet id1]]. ^ nil! ! !QuarkSpace methodsFor: 'searching' stamp: 'cf 9/2/2000 18:52'! q3Withq1: q1 q2: q2 space do: [:eachTriplet | (eachTriplet id1 == q1 and: [eachTriplet id2 == q2]) ifTrue: [^ eachTriplet id3]]. ^ nil! ! !QuarkSpace class methodsFor: 'instance creation' stamp: 'cf 5/31/2000 20:19'! new ^ super new initialize! ! !QuarkSpace class methodsFor: 'initialize-release' stamp: 'cf 8/31/2000 21:39'! buildStateMachine | eachState eachTransition | StateMachine _ IdentityDictionary new. Transitions do: [:each | eachState _ StateMachine at: each second ifAbsentPut: [State new]. eachTransition _ Transition targetState: each third action: (each at: 4 ifAbsent: [nil]). eachState addTransition: eachTransition forTrigger: each first]! ! !QuarkSpace class methodsFor: 'initialize-release' stamp: 'cf 8/31/2000 21:37'! initialize "QuarkSpace initialize" LineBreaks _ CharacterSet new. LineBreaks add: Character cr. LineBreaks add: Character lf. CharacterSets _ IdentityDictionary new. CharacterSets at: #quote put: (CharacterSet newFrom: '"'). CharacterSets at: #startToken put: (CharacterSet newFrom: '<'). CharacterSets at: #endToken put: (CharacterSet newFrom: '>'). CharacterSets at: #numerical put: (CharacterSet newFrom: '-+*/^()0123456789e.,'). CharacterSets at: #endNumerical put: ((CharacterSet newFrom: '-+*/^()0123456789e.,') complement). DiscardableTriggers _ IdentitySet newFrom: #(quote startToken endToken endNumerical). Transitions _ #( (startToken outside inToken) (endToken inToken outside tokenToId:) (numerical outside inNumerical) (endNumerical inNumerical outside numberToId:) (quote outside inString) (quote inString outside stringToId:) ). self buildStateMachine. "Also support blobs, bits, bytes."! ! !QuarkSpace class methodsFor: 'testing' stamp: 'cf 9/2/2000 18:53'! test1 "QuarkSpace test1" | space | space _ self new parseStream: (ReadStream on: ' "Mannby" "Mannby" "Fred" "Claes-Fredrik" "425 556 3038" '). (space q1Withq2: (space tokenToId: 'is-last-name-of') q3: (space tokenToId: 'mannby')) = (space stringToId: 'Mannby') ifFalse: [self halt]. (space collectq1Withq2: (space tokenToId: 'is-last-name-of') q3: (space tokenToId: 'mannby')) someElement = (space stringToId: 'Mannby') ifFalse: [self halt]. (space collectq1Withq2: (space tokenToId: 'is-last-name-of') q3: (space tokenToId: 'mannby')) size == 1 ifFalse: [self halt]. ^ space! ! !QuarkSpace class methodsFor: 'testing' stamp: 'cf 8/17/2000 13:29'! test2 "QuarkSpace test2" ^ self new parseStream: (FileStream readOnlyFileNamed: 'Tangie:Users:Fred:CD1:The Atlas:Atlas Project:Fred:TokensToQuarks:Test.qrk')! ! !QuarkSpace class methodsFor: 'testing' stamp: 'cf 9/2/2000 19:05'! test3Contacts "QuarkSpace test3Contacts" "Collect relationships from first line, e.g. First Name => . Create token for person, from first and last name, or if both empty, use serial number. Create relationships for non-empty cells only. Ignore blank lines." | space mannbys firstNames | space _ self new parseTabDelimitedTableWithHeaderStream: (FileStream readOnlyFileNamed: 'Tangie:Users:Fred:CD1:The Atlas:Atlas Project:Fred:Docs:Contacts.txt') withSignature: 'msoe5-contact'. mannbys _ space collectq3Withq1: (space stringToId: 'Mannby') q2: (space tokenToId: 'is-msoe5-contact-Last Name-of'). firstNames _ mannbys collect: [:each | space q1Withq2: (space tokenToId: 'is-msoe5-contact-First Name-of') q3: each]. firstNames detect: [:each | each = (space stringToId: 'Roger')] ifNone: [self halt]. ^ space! ! !State methodsFor: 'initializing' stamp: 'cf 8/31/2000 20:13'! initialize triggers _ IdentitySet new: 3. transitions _ IdentityDictionary new: 3.! ! !State methodsFor: 'accessing' stamp: 'cf 8/31/2000 20:28'! addTransition: aTransition forTrigger: aTrigger transitions at: aTrigger put: aTransition. self addTrigger: aTrigger.! ! !State methodsFor: 'accessing' stamp: 'cf 8/31/2000 20:12'! addTrigger: aTrigger ^ triggers add: aTrigger! ! !State methodsFor: 'accessing' stamp: 'cf 8/31/2000 20:12'! transitions ^ transitions! ! !State methodsFor: 'accessing' stamp: 'cf 8/31/2000 20:11'! triggers ^ triggers! ! !State class methodsFor: 'instance creation' stamp: 'cf 8/31/2000 20:25'! new ^ super new initialize! ! !String methodsFor: 'testing' stamp: 'cf 9/2/2000 13:51'! isString ^ true! ! !StringComposer methodsFor: 'accessing' stamp: 'cf 9/2/2000 18:01'! pattern ^ pattern! ! !StringComposer methodsFor: 'initializing' stamp: 'cf 9/2/2000 17:58'! completeWith: aValueList self completePartialPattern: pattern with: aValueList! ! !StringComposer methodsFor: 'initializing' stamp: 'cf 9/2/2000 15:56'! initialize type _ #simple! ! !StringComposer methodsFor: 'initializing' stamp: 'cf 9/2/2000 16:58'! pattern: aPattern pattern _ OrderedCollection new: aPattern size. aPattern do: [:each | each isSymbol ifTrue: [type _ each] ifFalse: [each isString ifTrue: [pattern add: each] ifFalse: [ (each isSequenceable and: [each first isSymbol]) ifTrue: [pattern add: (StringComposer pattern: each)] ifFalse: [pattern add: each]]]]! ! !StringComposer methodsFor: 'composing' stamp: 'cf 9/2/2000 16:13'! composeWith: aValueList | answer | answer _ ReadWriteStream on: (String new: 100). (self composeWith: aValueList on: answer) ifTrue: [^ answer contents] ifFalse: [^ String new]! ! !StringComposer methodsFor: 'composing' stamp: 'cf 9/2/2000 18:04'! composeWith: aValueList on: aStream | value | pattern do: [:each | each isNumber ifTrue: [value _ aValueList at: each ifAbsent: [^false]. (type == #allRequired and: [value isEmpty]) ifTrue: [^false]. aStream nextPutAll: value asString] ifFalse: [ each isString ifTrue: [aStream nextPutAll: each] ifFalse: [ each isSequenceable ifTrue: [value _ (aValueList at: each first ifAbsent: [^false]) at: each second ifAbsent: [^false]. (type == #allRequired and: [value isEmpty]) ifTrue: [^false]. aStream nextPutAll: value] ifFalse: [ value _ each composeWith: aValueList. (type == #allRequired and: [value isEmpty]) ifTrue: [^false]. aStream nextPutAll: value. (type == #or and: [value isEmpty not]) ifTrue: [^true]]]]]. ^ true! ! !StringComposer methodsFor: 'private' stamp: 'cf 9/2/2000 18:01'! completePartialPattern: aPart with: aValueList | remainingValues | aValueList isEmpty ifTrue: [^ aValueList]. remainingValues _ Array newFrom: aValueList. aPart doWithIndex: [:each :index | each == #hole ifTrue: [aPart at: index put: remainingValues first. remainingValues _ remainingValues copyFrom: 2 to: remainingValues size] ifFalse: [ (each isSequenceable and: [each isString not and: [each isSymbol not]]) ifTrue: [remainingValues _ self completePartialPattern: each with: remainingValues] ifFalse: [ (each isKindOf: StringComposer) ifTrue: [remainingValues _ each completePartialPattern: each pattern with: remainingValues]]]]. ^ remainingValues! ! !StringComposer class methodsFor: 'instance creation' stamp: 'cf 9/2/2000 15:56'! pattern: aPattern ^ self new initialize pattern: aPattern! ! !StringQuery methodsFor: 'initializing' stamp: 'cf 9/2/2000 17:00'! expression: anExpression values _ OrderedCollection new: anExpression size. anExpression do: [:each | each isSymbol ifTrue: [each == #case ifTrue: [isCaseSensitive _ true] ifFalse: [ each == #noCase ifTrue: [isCaseSensitive _ false] ifFalse: [ each == #partial ifTrue: [isPartial _ true] ifFalse: [ each == #notPartial ifTrue: [isPartial _ false] ifFalse: [ each == #regEx ifTrue: [usesRegEx _ true] ifFalse: [ each == #notRegEx ifTrue: [usesRegEx _ false] ifFalse: [ booleanFunction _ each]]]]]]] ifFalse: [each isString ifTrue: [values add: each] ifFalse: [ each isSequenceable ifTrue: [values add: (StringQuery with: each case: isCaseSensitive)] ifFalse: [values add: each]]]]! ! !StringQuery methodsFor: 'initializing' stamp: 'cf 9/2/2000 15:01'! initialize isCaseSensitive _ false. isPartial _ true. byWord _ false. delimiters _ CharacterSet separators. delimiters addAll: '!!@#$%^&*()_+`~-=[]\{}|;'':",./<>?'. usesRegEx _ false. booleanFunction _ #or. values _ nil.! ! !StringQuery methodsFor: 'initializing' stamp: 'cf 9/2/2000 13:59'! isCaseSensitive: aBoolean isCaseSensitive _ aBoolean! ! !StringQuery methodsFor: 'searching' stamp: 'cf 9/2/2000 14:05'! indexInCollection: aCollection aCollection doWithIndex: [:each :index | (self matchesString: each) ifTrue: [^ index]]! ! !StringQuery methodsFor: 'searching' stamp: 'cf 9/2/2000 16:03'! matchesString: aString byWord ifTrue: [self halt]. "Not yet implemented" booleanFunction == #or ifTrue: [values anySatisfy: [:each | each isString ifTrue: [self value: each matches: aString] ifFalse: [each matchesString: aString]]] ifFalse: [ booleanFunction == #and ifTrue: [values do: [:each | each isString ifTrue: [(self value: each matches: aString) ifFalse: [^ false]] ifFalse: [each matchesString: aString]]. ^ true] ifFalse: [self halt. "Unsupported boolean function."]]! ! !StringQuery methodsFor: 'searching' stamp: 'cf 9/2/2000 15:10'! value: aString matches: domainString byWord ifTrue: [self halt]. "Not yet implemented" usesRegEx ifTrue: [self halt]. "Not yet implemented" isPartial ifFalse: [^ aString = domainString]. ^ (domainString findString: aString startingAt: 1 caseSensitive: isCaseSensitive) > 0! ! !StringQuery class methodsFor: 'instance creation' stamp: 'cf 9/2/2000 13:59'! with: anExpression ^ self new initialize expression: anExpression! ! !StringQuery class methodsFor: 'instance creation' stamp: 'cf 9/2/2000 13:59'! with: anExpression case: isCaseSensitive ^ (self new initialize isCaseSensitive: isCaseSensitive) expression: anExpression! ! !Symbol methodsFor: 'testing' stamp: 'cf 9/2/2000 13:51'! isString ^ false! ! !Symbol methodsFor: 'testing' stamp: 'cf 9/2/2000 13:51'! isSymbol ^ true! ! !Transition methodsFor: 'accessing' stamp: 'cf 8/31/2000 20:14'! action ^ action! ! !Transition methodsFor: 'accessing' stamp: 'cf 8/31/2000 20:14'! targetState ^ targetState! ! !Transition methodsFor: 'accessing' stamp: 'cf 8/31/2000 20:31'! targetState: aTargetState action: anAction targetState _ aTargetState. action _ anAction.! ! !Transition class methodsFor: 'instance creation' stamp: 'cf 8/31/2000 20:29'! targetState: aTargetState action: anAction ^ self new targetState: aTargetState action: anAction! ! !Triplet methodsFor: 'printing' stamp: 'cf 9/2/2000 18:42'! printOn: aStream aStream nextPut: Character cr; nextPut: ${; nextPutAll: id1 printString; nextPut: $ ; nextPutAll: id2 printString; nextPut: $ ; nextPutAll: id3 printString; nextPut: $}! ! !Triplet methodsFor: 'accessing' stamp: 'cf 8/31/2000 21:50'! at: index put: value index = 1 ifTrue: [id1 _ value. ^self]. index = 2 ifTrue: [id2 _ value. ^self]. index = 3 ifTrue: [id3 _ value. ^self]. "self halt." "More than 3 quarks on a line, for example. Ignore for now. Being used for comments."! ! !Triplet methodsFor: 'accessing' stamp: 'cf 5/31/2000 19:58'! id1 ^ id1! ! !Triplet methodsFor: 'accessing' stamp: 'cf 5/31/2000 19:58'! id1: anId1 id2: anId2 id3: anId3 id1 _ anId1. id2 _ anId2. id3 _ anId3.! ! !Triplet methodsFor: 'accessing' stamp: 'cf 5/31/2000 19:58'! id2 ^ id2! ! !Triplet methodsFor: 'accessing' stamp: 'cf 5/31/2000 19:58'! id3 ^ id3! ! !Triplet methodsFor: 'comparing' stamp: 'cf 9/1/2000 21:52'! = aTriplet ^ id1 == aTriplet id1 and: [id2 == aTriplet id2 and: [id3 == aTriplet id3]]! ! !Triplet class methodsFor: 'instance creation' stamp: 'cf 5/31/2000 19:57'! id1: anId1 id2: anId2 id3: anId3 | newInstance | newInstance _ self new. newInstance id1: anId1 id2: anId2 id3: anId3. ^ newInstance! ! QuarkSpace initialize!