View difference between Paste ID: kuDmLwYq and AwdwCau8
SHOW: | | - or go back to the newest paste.
1-
use Transitional;
1+
2
--
3
--   Script by Lars Rönnbäck
4
--   Based on the paper "Modeling Conflicting, Unreliable, and Varying Information"
5-
--   Script by Lars Rönnbäck - latest version is always here: https://pastebin.com/AwdwCau8
5+
--   https://www.researchgate.net/publication/329352497_Modeling_Conflicting_Unreliable_and_Varying_Information
6-
--	
6+
7
--   This script creates a relationally modeled implementation of Transitional Modeling, with 
8
--   some limitiations due to missing features in SQL Server.
9-
--   Full-text preprint available on ResearchGate: https://bit.ly/2A7J4Rb
9+
10
--   Version: 20181217.2   Better XML in the views.
11
--
12-
--   some limitiations due to missing features in SQL Server. Note that this is only intended 
12+
--   TODO: Add stored procedure that takes similar XML input and automagically populates the 
13-
--   as a prototype in which concepts can be tested for educational purposes.
13+
--         underlying model.
14
--
15-
--   Version: 20181220.1   Added stored procedure that simplifies data insertion.
15+
16-
--						   Cleaned up examples and added posit types.
16+
17-
--            20181217.2   Better XML in the views (old version: https://pastebin.com/kuDmLwYq).
17+
18
drop table if exists [Assertion];
19
drop table if exists [Posit];
20-
drop procedure if exists [Assert];
20+
21-
drop view if exists [Check_for_Contradictions];
21+
22
drop table if exists [Appearance];
23
drop table if exists [Role];
24
drop table if exists [Thing];
25
26
-- A table to store the unique identifiers of things.
27
-- Where a thing is that which is sufficiently distinguishable 
28
-- from something else to be told apart.
29
create table [Thing] (
30
	[UID] uniqueidentifier not null default NEWSEQUENTIALID(), 
31
	-- Enforce uniqueness of the unique identifiers.
32
	-- Note that primary keys enforce uniqueness as well as cluster
33
	-- the underlying table for better performance, and is needed
34
	-- in order to reference these using foreign key references.
35
	constraint [unique_and_referenceable_UID] primary key clustered (
36
		[UID]
37
	)
38
);
39
40
create table [Role] (
41
	[RoleUID] uniqueidentifier not null,
42
	[Role] varchar(555) not null,
43
	constraint [Role_is_Thing] foreign key (
44
		[RoleUID]
45
	) references [Thing]([UID]),
46
	constraint [referenceable_RoleUID] primary key clustered (
47
		[RoleUID]
48
	),
49
	constraint [unique_Role] unique nonclustered (
50
		[Role]
51
	)
52
);
53
54
/*
55
----------- Excerpt from: Modeling Conflicting, Unreliable, and Varying Information -----------
56
def. of universal 
57
A body of information is said to be universal iff positors agree on all appearances.
58
-----------------------------------------------------------------------------------------------
59
60
In order to disagree you must first agree upon something upon which the difference in 
61
opinion lies. At the very least, positors must agree on appearances. In other words
62
if two positors want to have an opinion about something, they must first come to the 
63
conclusion that this something boils down to the same unique identifier for both of them 
64
and that they mean the same when they talk about the roles it may appear in.
65
66
We will assume that talk about "Archie's beard" by any positor means that it is the 
67
same Archie and the same property they are talking about.
68
*/
69
create table [Appearance] (
70
	[AppearanceUID] uniqueidentifier not null,
71
	[ThingUID] uniqueidentifier not null,
72
	[RoleUID] uniqueidentifier not null,
73
	constraint [Appearance_is_Thing] foreign key (
74
		[AppearanceUID]
75
	) references [Thing]([UID]),
76
	constraint [ensure_existing_Thing] foreign key (
77
		[ThingUID]
78
	) references [Thing]([UID]),
79
	constraint [ensure_existing_Role] foreign key (
80
		[RoleUID]
81
	) references [Role]([RoleUID]),
82
	constraint [referenceable_AppearanceUID] primary key clustered (
83-
	constraint [existing_Thing] foreign key (
83+
84
	),
85
	constraint [unique_Appearance] unique nonclustered (
86-
	constraint [existing_Role] foreign key (
86+
87
		[RoleUID]
88
	)
89
);
90
91
create table [DereferencingSet] (
92
	[DereferencingSetUID] uniqueidentifier not null,
93
	constraint [DereferencingSet_is_Thing] foreign key (
94
		[DereferencingSetUID]
95
	) references [Thing]([UID]),
96
	constraint [unique_and_referenceable_DereferencingSetUID] primary key clustered (
97
		[DereferencingSetUID]
98
	)
99
);
100
101
create table [Dereference] (
102
	[DereferencingSetUID] uniqueidentifier not null,
103
	[AppearanceUID] uniqueidentifier not null,
104
	constraint [reference_to_DereferencingSet] foreign key (
105
		[DereferencingSetUID]
106
	) references [DereferencingSet]([DereferencingSetUID]),
107
	constraint [reference_to_Appearance] foreign key (
108
		[AppearanceUID]
109
	) references [Appearance]([AppearanceUID]),
110
	constraint [unique_Dereference] primary key clustered (
111
		[DereferencingSetUID],
112
		[AppearanceUID]
113
	)
114
);	
115
116
/*
117
----------- Excerpt from: Modeling Conflicting, Unreliable, and Varying Information -----------
118
def. of canonical
119
A body of information is said to be canonical iff all assertions
120
are made against posits without negated values.
121
-----------------------------------------------------------------------------------------------
122
123
In practice, the value of a posit may be of any data type, primitive or complex, but due to 
124
SQL Server lacking support for generics (looks like <T> in many programming languages) we 
125
have to limit the Value column to varchar(max). Appearance time may also be any time type, 
126
exact or fuzzy, in order to represent that the value appeared exactly since some specified 
127
time or inexactly within some period of time. Here the AppearanceTime column is limited 
128
to a datetime.
129
130
Finally, in order to represent information, canonical form is used, which simply means that
131
values are stored without negation, for example "red" is acceptable, and "not red" is not.
132
Opposite opinions are instead handled using negative Reliability in assertions.
133
*/
134
create table [Posit] (
135
	[PositUID] uniqueidentifier not null,
136
	[DereferencingSetUID] uniqueidentifier not null,
137
	[Value] varchar(max) null, 
138
	[AppearanceTime] datetime null,
139
	constraint [ensure_existing_DereferencingSet] foreign key (
140
		[DereferencingSetUID]
141
	) references [DereferencingSet]([DereferencingSetUID]),
142
	constraint [Posit_is_Thing] foreign key (
143
		[PositUID]
144
	) references [Thing]([UID]),
145-
	[AppearanceTime] datetime not null,
145+
146-
	constraint [existing_DereferencingSet] foreign key (
146+
147
	)
148
);
149
150
/*
151
----------- Excerpt from: Modeling Conflicting, Unreliable, and Varying Information -----------
152
def. of a body of information
153
A body of information is a set of true assertions.
154
155
def. of exclusive
156
A body of information is said to be exclusive iff no assertions
157
in which only the reliability differs exist.
158
-----------------------------------------------------------------------------------------------
159
160
We will assume that any data inserted into this table represents true assertions. We will not
161
constrain the Reliability column, but in practice it should be in the interval [-1, 1].  
162
The constraint [unique_Assertion] ensures that the stored assertions are exclusive, so that 
163
there is no ambiguity with respect to the assigned Reliability.
164
*/
165
create table [Assertion] (
166
	[AssertionUID] uniqueidentifier not null,
167
	[PositorUID] uniqueidentifier not null,
168
	[PositUID] uniqueidentifier not null,
169
	[Reliability] decimal(3,2) not null,
170
	[AssertionTime] datetime not null,
171
	constraint [Assertion_is_Thing] foreign key (
172
		[AssertionUID]
173
	) references [Thing]([UID]),
174
	constraint [ensure_existing_Positor] foreign key (
175
		[PositorUID]
176
	) references [Thing]([UID]),
177
	constraint [ensure_existing_Posit] foreign key (
178
		[PositUID]
179
	) references [Posit]([PositUID]),
180
	constraint [referenceable_AssertionUID] primary key nonclustered (
181-
	constraint [existing_Positor] foreign key (
181+
182
	),
183
	constraint [unique_Assertion] unique clustered (
184-
	constraint [existing_Posit] foreign key (
184+
185
		[PositUID],
186
		[AssertionTime]
187
	)
188
);
189
190
go
191
create or alter view [v_Posit] 
192
as
193
select
194
	p.[PositUID],
195
	p.[DereferencingSetUID],
196
	p.[Value],
197
	p.[AppearanceTime],
198
	(
199
		select
200
			p.[PositUID] as [@UID],
201
			p.[DereferencingSetUID] as [DereferencingSet/@UID],
202
			(
203
				select
204
					a.[ThingUID] as [@UID],
205
					r.[Role] as [@Role]
206
				from
207-
			p.[PositUID] as [@PositUID],
207+
208-
			p.[AppearanceTime] as [@AppearanceTime],
208+
209-
			p.[DereferencingSetUID] as [DereferencingSet/@DereferencingSetUID],
209+
210
				on
211
					d.[DereferencingSetUID] = s.[DereferencingSetUID]
212-
					a.[AppearanceUID] as [@AppearanceUID],
212+
213-
					a.[ThingUID] as [@ThingUID],
213+
214
				on
215
					a.[AppearanceUID] = d.[AppearanceUID]
216
				join
217
					[Role] r
218
				on
219
					r.[RoleUID] = a.[RoleUID]
220
				where
221
					s.[DereferencingSetUID] = p.[DereferencingSetUID]
222
				order by
223
					r.[RoleUID] asc
224
				for xml path('Appearance'), type
225
			) as [DereferencingSet],
226
			p.[Value],
227
			p.[AppearanceTime] 
228
		for xml path('Posit'), type
229
	) as [PositXML]
230
from
231
	[Posit] p
232
233
go
234
create or alter view [v_Assertion]
235-
			p.[Value]
235+
236
select
237
	a.[AssertionUID],
238
	a.[PositorUID],
239
	a.[PositUID],
240
	p.[DereferencingSetUID],
241
	p.[Value],
242
	p.[AppearanceTime],
243
	a.[Reliability],
244
	a.[AssertionTime],
245
	(
246
		select
247
			a.[AssertionUID] as [@UID],
248
			a.[PositorUID] as [Positor/@UID],
249
			p.[PositXML].query('.'),
250
			a.[Reliability] as [Reliability],
251
			a.[AssertionTime] as [AssertionTime]
252
		for xml path('Assertion'), type
253
	) as [AssertionXML]
254
from
255-
			a.[AssertionUID] as [@AssertionUID],
255+
256-
			a.[PositorUID] as [@PositorUID],
256+
257-
			a.[Reliability] as [@Reliability],
257+
258-
			a.[AssertionTime] as [@AssertionTime],
258+
259-
			p.[PositXML].query('.')
259+
260
go
261
262
--------------------------------------- PROPERTIES ---------------------------------------
263
264
-- we have to use tables since the OUTPUT clause only works for tables
265
drop table if exists #A;
266
drop table if exists #B;
267
drop table if exists #M;
268
drop table if exists #S;
269
drop table if exists #D;
270-
/* 
270+
create table #A([UID] uniqueidentifier not null primary key); -- Archie
271-
------------------------------------------- XML FORMAT -------------------------------------------
271+
create table #B([UID] uniqueidentifier not null primary key); -- Bella
272-
  Specify UID for already known things and some Label for unknown. Bracketed attributes
272+
create table #M([UID] uniqueidentifier not null primary key); -- Modeler
273-
  are optional. Labels will result in new things being created, one for each unique label.
273+
create table #S([UID] uniqueidentifier not null primary key); -- Script
274
create table #D([UID] uniqueidentifier not null primary key); -- Disagreer
275-
	<Assertion PositorUID="<UID|Label>" Reliability="1.00" AssertionTime="2018-12-13T15:30:00">
275+
276-
	  <Posit [PositUID="<UID>"] AppearanceTime="2018-12-01T12:00:00">
276+
-- create the Archie thing
277-
		<DereferencingSet [DereferencingSetUID="<UID>"]>
277+
insert into [Thing]([UID]) output inserted.[UID] into #A values (DEFAULT);
278-
		  <Appearance [AppearanceUID="<UID>"] ThingUID="<UID|Label>" Role="has beard" />
278+
-- create the Bella thing
279-
		</DereferencingSet>
279+
insert into [Thing]([UID]) output inserted.[UID] into #B values (DEFAULT);
280-
		<Value>fluffy red</Value>
280+
-- create the Modeler thing
281-
	  </Posit>
281+
insert into [Thing]([UID]) output inserted.[UID] into #M values (DEFAULT);
282-
	</Assertion>
282+
-- create the Script thing
283
insert into [Thing]([UID]) output inserted.[UID] into #S values (DEFAULT);
284-
  Note that AssertionUID cannot be specified. Assertions can never be altered once they've been 
284+
-- create the Disagreer thing
285-
  created. 
285+
insert into [Thing]([UID]) output inserted.[UID] into #D values (DEFAULT);
286-
--------------------------------------------------------------------------------------------------
286+
287
-- we now have five things
288-
create or alter procedure Assert (
288+
289-
	@assertion xml OUTPUT
289+
290-
) 
290+
-- create a role thing and an appearance thing
291
drop table if exists #Role1;
292-
begin
292+
drop table if exists #Appearance1;
293-
	set nocount on;
293+
create table #Role1([UID] uniqueidentifier not null primary key); 
294
create table #Appearance1([UID] uniqueidentifier not null primary key); 
295-
	-- create a lookup table 
295+
insert into [Thing]([UID]) output inserted.[UID] into #Role1 values (DEFAULT);
296-
	create table #Thing (
296+
insert into [Thing]([UID]) output inserted.[UID] into #Appearance1 values (DEFAULT);
297-
		[ThingUID] uniqueidentifier not null primary key,
297+
298-
		[UID_or_Label] varchar(555) not null
298+
-- create a role
299-
	);
299+
insert into [Role]([RoleUID], [Role]) 
300
select [UID], 'has beard' 
301-
	-- is a posit set already referenced through a UID?
301+
from #Role1;
302-
	declare @PositUID uniqueidentifier = @assertion.value(
302+
303-
		'/Assertion[1]/Posit[1]/@PositUID', 
303+
-- check what the role looks like
304-
		'uniqueidentifier'
304+
select * from [Role];
305-
	);
305+
306
-- create an appearance
307-
	-- if not it needs to be built
307+
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
308-
	if @PositUID is null
308+
select app.[UID], Archie.[UID], r.[RoleUID] 
309-
	begin
309+
from [Role] r, #Appearance1 app, #A Archie 
310-
		-- is a dereferencing set already referenced through a UID?
310+
where r.[Role] = 'has beard';
311-
		declare @DereferencingSetUID uniqueidentifier = @assertion.value(
311+
312-
			'/Assertion[1]/Posit[1]/DereferencingSet[1]/@DereferencingSetUID', 
312+
-- we now have one appearance
313-
			'uniqueidentifier'
313+
select * from [Appearance];
314-
		);
314+
315
-- create a dereferencing set thing
316-
		if @DereferencingSetUID is not null
316+
drop table if exists #DereferencingSet1;
317-
		begin
317+
create table #DereferencingSet1([UID] uniqueidentifier not null primary key); 
318-
			if not exists (
318+
insert into [Thing]([UID]) output inserted.[UID] into #DereferencingSet1 values (DEFAULT);
319-
				select [DereferencingSetUID] from [DereferencingSet] 
319+
320-
				where [DereferencingSetUID] = @DereferencingSetUID
320+
-- create a dereferencing set
321-
			)
321+
insert into [DereferencingSet]([DereferencingSetUID]) 
322-
			raiserror('The referenced @DereferencingSetUID does not exist', 10, 1);
322+
select [UID]
323-
		end 
323+
from #DereferencingSet1;
324-
		else	
324+
325-
		begin
325+
-- add the appearance to the dereferencing set
326-
			-- check if given AppareanceUID:s exist
326+
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
327-
			if exists (
327+
select s.[UID], app.[UID]
328-
				select x.[AppearanceUID]
328+
from #DereferencingSet1 s, #Appearance1 app;
329-
				from (
329+
330-
					select distinct 
330+
-- create a posit thing
331-
						Appearance.value('@AppearanceUID', 'uniqueidentifier') as [AppearanceUID]
331+
drop table if exists #Posit1;
332-
					from @assertion.nodes(
332+
create table #Posit1([UID] uniqueidentifier not null primary key);
333-
						'/Assertion/Posit/DereferencingSet/Appearance[@AppearanceUID]'
333+
insert into [Thing]([UID]) output inserted.[UID] into #Posit1 values (DEFAULT);
334-
					) as T(Appearance) 
334+
335-
				) x
335+
-- create a posit
336-
				left join [Appearance] a
336+
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
337-
				on a.[AppearanceUID] = x.[AppearanceUID]
337+
select p.[UID], s.[UID], 'fluffy red', '2018-12-01 12:00'
338-
				where a.[AppearanceUID] is null
338+
from #Posit1 p, #DereferencingSet1 s;
339-
			)
339+
340-
			raiserror('The referenced @AppearanceUID does not exist', 10, 1);
340+
-- we now have one posit
341
select * from [Posit];
342-
			-- create a table to hold appearances
342+
343-
			create table #Appearance (
343+
-- now the posit is complete
344-
				AppearanceUID uniqueidentifier not null primary key, 
344+
select * from [v_Posit];
345-
				ThingUID uniqueidentifier not null,
345+
346-
				RoleUID uniqueidentifier not null
346+
-- let Bella assert this, so first create an assertion thing
347-
			);
347+
drop table if exists #Assertion1;
348
create table #Assertion1([UID] uniqueidentifier not null primary key);
349-
			-- add existing and referenced appearances
349+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion1 values (DEFAULT);
350-
			insert into #Appearance 
350+
351-
			select a.* 
351+
-- create an assertion
352-
			from (
352+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
353-
				select distinct 
353+
select a.[UID], Bella.[UID], p.[UID], 1, '2018-12-13 15:30'
354-
					Appearance.value('@AppearanceUID', 'uniqueidentifier') as [AppearanceUID]
354+
from #Assertion1 a, #B Bella, #Posit1 p;
355-
				from @assertion.nodes(
355+
356-
					'/Assertion/Posit/DereferencingSet/Appearance[@AppearanceUID]'
356+
-- now we have one assertion
357-
				) as T(Appearance) 
357+
select * from [Assertion];
358-
			) x
358+
359-
			join [Appearance] a
359+
-- now the assertion is complete
360-
			on a.[AppearanceUID] = x.[AppearanceUID];
360+
select * from [v_Assertion]
361
order by [DereferencingSetUID], [PositorUID], [AppearanceTime] desc, [AssertionTime] desc;
362-
			declare @matches int = 0;
362+
363-
			-- create missing things and populate the lookup table
363+
-- create another posit thing
364-
			merge [Thing] t
364+
drop table if exists #Posit2;
365-
			using (
365+
create table #Posit2([UID] uniqueidentifier not null primary key);
366-
				select distinct 
366+
insert into [Thing]([UID]) output inserted.[UID] into #Posit2 values (DEFAULT);
367-
					Appearance.value('@ThingUID', 'varchar(555)') as [UID_or_Label]
367+
368-
				from @assertion.nodes(
368+
-- create that posit
369-
					'/Assertion/Posit/DereferencingSet/Appearance[not(@AppearanceUID)]'
369+
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
370-
				) as T(Appearance) 
370+
select p.[UID], s.[UID], 'shaved clean', '2018-12-01 12:00'
371-
			) i on i.[UID_or_Label] = cast(t.[UID] as varchar(555))
371+
from #Posit2 p, #DereferencingSet1 s;
372-
			when not matched then insert values(DEFAULT)
372+
373-
			when matched then update set @matches = @matches + 1 
373+
-- we now have two posits
374-
			output inserted.[UID], i.[UID_or_Label] into #Thing;
374+
select * from [Posit];
375
376-
			-- create a lookup table 
376+
-- let the Disagreer assert this, so first create another assertion thing
377-
			create table #Role (
377+
drop table if exists #Assertion2;
378-
				[RoleUID] uniqueidentifier not null primary key,
378+
create table #Assertion2([UID] uniqueidentifier not null primary key);
379-
				[Role] varchar(555) not null
379+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion2 values (DEFAULT);
380-
			);
380+
381
-- create another assertion
382-
			-- lookup or create the roles
382+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
383-
			merge [Thing] t
383+
select a.[UID], Disagreer.[UID], p.[UID], 1, '2018-12-13 15:30'
384-
			using (
384+
from #Assertion2 a, #D Disagreer, #Posit2 p;
385
386-
					r.[RoleUID],
386+
-- now that assertion is also complete
387-
					x.[Role]
387+
-- so Bella and the Disagreer have conflicting views of Archie's beard
388-
				from (
388+
select * from [v_Assertion]
389-
					select  
389+
390-
						Appearance.value('@Role', 'varchar(555)') as [Role]
390+
391-
					from @assertion.nodes(
391+
-- let the Disagreer disagree on the posit Bella asserted
392-
						'/Assertion/Posit/DereferencingSet/Appearance[not(@AppearanceUID)]'
392+
drop table if exists #Assertion3;
393-
					) as T(Appearance) 
393+
create table #Assertion3([UID] uniqueidentifier not null primary key);
394-
				) x
394+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion3 values (DEFAULT);
395-
				left join [Role] r
395+
396-
				on x.[Role] = r.[Role]
396+
-- create another assertion
397-
			) i on i.[RoleUID] = t.[UID]
397+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
398-
			when not matched then insert values(DEFAULT)
398+
select a.[UID], Disagreer.[UID], p.[UID], -1, '2018-12-13 15:35'
399-
			when matched then update set @matches = @matches + 1 
399+
from #Assertion3 a, #D Disagreer, #Posit1 p;
400-
			output inserted.[UID], i.[Role] into #Role;
400+
401
-- so Bella and the Disagreer also disagree on the posit stating it is fluffy red
402-
			-- add missing roles to Role
402+
select * from [v_Assertion]
403-
			merge [Role] r
403+
404-
			using #Role rlkp
404+
405-
			on rlkp.[RoleUID] = r.[RoleUID]
405+
406-
			when not matched then insert values (rlkp.[RoleUID], rlkp.[Role]);
406+
-- first create an assertion thing
407
drop table if exists #Assertion4;
408-
			-- lookup or create the appearances
408+
create table #Assertion4([UID] uniqueidentifier not null primary key);
409-
			merge [Thing] t
409+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion4 values (DEFAULT);
410-
			using (
410+
411
-- create an assertion
412-
					a.[AppearanceUID],
412+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
413-
					tlkp.[ThingUID],
413+
select a.[UID], Bella.[UID], p.[UID], 0.05, '2018-12-13 15:35'
414-
					rlkp.[RoleUID]
414+
from #Assertion4 a, #B Bella, #Posit2 p;
415-
				from (
415+
416-
					select  
416+
417-
						Appearance.value('@ThingUID', 'varchar(555)') as [UID_or_Label],
417+
select * from [v_Assertion]
418-
						Appearance.value('@Role', 'varchar(555)') as [Role]
418+
419-
					from @assertion.nodes(
419+
420-
						'/Assertion/Posit/DereferencingSet/Appearance[not(@AppearanceUID)]'
420+
-- create another posit thing
421-
					) as T(Appearance) 
421+
drop table if exists #Posit3;
422-
				) x
422+
create table #Posit3([UID] uniqueidentifier not null primary key);
423-
				join #Thing tlkp 
423+
insert into [Thing]([UID]) output inserted.[UID] into #Posit3 values (DEFAULT);
424-
				on tlkp.[UID_or_Label] = x.[UID_or_Label]
424+
425-
				join #Role rlkp
425+
-- create that posit
426-
				on rlkp.[Role] = x.[Role]
426+
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
427-
				left join [Appearance] a
427+
select p.[UID], s.[UID], 'shaved clean', '2018-12-01 13:00'
428-
				on a.[ThingUID] = tlkp.[ThingUID] and a.[RoleUID] = rlkp.[RoleUID]
428+
from #Posit3 p, #DereferencingSet1 s;
429-
			) i on i.[AppearanceUID] = t.[UID]
429+
430-
			when not matched then insert values(DEFAULT)
430+
-- we now have three posits
431-
			when matched then update set @matches = @matches + 1 
431+
select * from [Posit];
432-
			output inserted.[UID], i.[ThingUID], i.[RoleUID] into #Appearance;
432+
433
-- create another assertion thing
434-
			-- add missing apperances to Appearance
434+
drop table if exists #Assertion5;
435-
			merge [Appearance] a
435+
create table #Assertion5([UID] uniqueidentifier not null primary key);
436-
			using #Appearance alkp
436+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion5 values (DEFAULT);
437-
			on alkp.[AppearanceUID] = a.[AppearanceUID]
437+
438-
			when not matched then insert values (alkp.[AppearanceUID], alkp.[ThingUID], alkp.[RoleUID]);
438+
-- create an assertion
439
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
440-
			declare @NumberOfAppearances int = (select count(*) from #Appearance);
440+
select a.[UID], Bella.[UID], p.[UID], 1, '2018-12-13 15:35'
441
from #Assertion5 a, #B Bella, #Posit3 p;
442-
			-- do these appearances already exist as a dereferencing set?
442+
443-
			set @DereferencingSetUID = (
443+
444-
				select d.DereferencingSetUID 
444+
445-
				  from [Dereference] d 
445+
446-
				left join #Appearance a on a.AppearanceUID = d.AppearanceUID
446+
447-
				group by d.DereferencingSetUID
447+
448-
				having COUNT(d.AppearanceUID) = @NumberOfAppearances
448+
449-
				   and COUNT(a.AppearanceUID) = @NumberOfAppearances
449+
450-
			);
450+
451
Let A be a body of information. The information in effect is a
452-
			-- if not it needs to be created
452+
453-
			if @DereferencingSetUID is null 
453+
454-
			begin
454+
455-
				create table #DereferencingSet (
455+
456-
					[DereferencingSetUID] uniqueidentifier not null primary key
456+
457-
				);
457+
458
   t ≤ t@.
459-
				insert into [Thing] 
459+
460-
				output inserted.[UID] into #DereferencingSet
460+
461-
				values (DEFAULT);
461+
462
   assertion !(P, p, 0, T0) exists with T ≤ T0 ≤ T@.
463-
				set @DereferencingSetUID = (select top 1 [DereferencingSetUID] from #DereferencingSet);
463+
464
   latest assertion time T for each combination of P, D, and v.
465-
				insert into [DereferencingSet] values (@DereferencingSetUID);
465+
466
467-
				insert into [Dereference] 
467+
468-
				select @DereferencingSetUID, [AppearanceUID]
468+
469-
				from #Appearance;
469+
470-
			end
470+
471-
		end -- end of building a dereference set
471+
472-
		-- now we have a @DereferencingSetUID
472+
473
	@assertionTime datetime
474-
		declare @Value varchar(max);
474+
475-
		declare @AppearanceTime datetime;
475+
476
with A1 as (
477-
		select  
477+
478-
			@Value = cast(Posit.query('Value/node()') as varchar(max)),
478+
		*
479-
			@AppearanceTime = Posit.value('@AppearanceTime', 'datetime')
479+
480-
		from @assertion.nodes(
480+
		[v_Assertion]
481-
			'/Assertion[1]/Posit[1]'
481+
	where
482-
		) as T(Posit);
482+
		[AppearanceTime] <= @appearanceTime
483
	and
484-
		-- check if it already exists
484+
		[AssertionTime] <= @assertionTime
485-
		set @PositUID = (
485+
486-
			select [PositUID]
486+
487-
			from [Posit]
487+
488-
			where [DereferencingSetUID] = @DereferencingSetUID
488+
		a.*
489-
			  and [Value] = @Value
489+
490-
			  and [AppearanceTime] = @AppearanceTime
490+
		A1 a
491-
		);
491+
	where
492
		a.[Reliability] <> 0
493-
		if @PositUID is null 
493+
	and
494-
		begin
494+
		a.[AppearanceTime] = (
495-
			-- create the posit
495+
			select
496-
			create table #Posit (
496+
				max(s.[AppearanceTime])
497-
				[PositUID] uniqueidentifier not null primary key
497+
			from
498-
			);
498+
				A1 s
499
			where
500-
			insert into [Thing] 
500+
				s.[PositorUID] = a.[PositorUID]
501-
			output inserted.[UID] into #Posit
501+
			and 
502-
			values (DEFAULT);
502+
				s.[DereferencingSetUID] = a.[DereferencingSetUID]
503
		)
504-
			set @PositUID = (select top 1 [PositUID] from #Posit);
504+
	and not exists (
505
		select
506-
			insert into [Posit] (
506+
			x.[AssertionUID]
507-
				[PositUID], 
507+
		from
508-
				[DereferencingSetUID], 
508+
			A1 x
509-
				[Value], 
509+
		where
510-
				[AppearanceTime]
510+
			x.[PositorUID] = a.[PositorUID]
511-
			)
511+
		and 
512-
			values (
512+
			x.[PositUID] = a.[PositUID]
513-
				@PositUID,
513+
		and			
514-
				@DereferencingSetUID,
514+
			x.[Reliability] = 0
515-
				@Value,
515+
		and
516-
				@AppearanceTime
516+
			x.[AssertionTime] between a.AssertionTime and @assertionTime
517-
			);
517+
518-
		end -- new posit created
518+
), 
519-
	end -- end of building posit
519+
A3 as (
520-
	-- now we have a @PositUID
520+
521
		a.*
522-
	declare @AssertionUID uniqueidentifier;
522+
523
		A2 a
524-
	-- create the assertion
524+
	where
525-
	create table #Assertion (
525+
		a.[AssertionTime] = (
526-
		[AssertionUID] uniqueidentifier not null primary key
526+
			select
527-
	);
527+
				max(s.[AssertionTime])
528
			from
529-
	insert into [Thing] 
529+
				A2 s
530-
	output inserted.[UID] into #Assertion
530+
			where
531-
	values (DEFAULT);
531+
				s.[PositorUID] = a.[PositorUID]
532
			and 
533-
	set @AssertionUID = (select top 1 [AssertionUID] from #Assertion);
533+
				s.[DereferencingSetUID] = a.[DereferencingSetUID]
534
			and	
535-
	-- A positor must be referenced through a UID or Label
535+
				s.[Value] = a.[Value]
536-
	declare @PositorUID_or_Label varchar(555) = @assertion.value(
536+
		)		
537-
		'/Assertion[1]/@PositorUID', 
537+
538-
		'varchar(555)'
538+
539-
	);
539+
	*
540
from 
541-
	if @PositorUID_or_Label is null
541+
	A3;
542-
	raiserror('No @PositorUID has been specified', 10, 1);
542+
543
544-
	-- is must either be a UID or a Label (and if it is a Label it is already created)
544+
545-
	declare @PositorUID uniqueidentifier = isnull(
545+
546-
		(select [ThingUID] from #Thing where [UID_or_Label] = @PositorUID_or_Label),
546+
547-
		(select [UID] from [Thing] where cast([UID] as varchar(555)) = @PositorUID_or_Label)
547+
548-
	);
548+
549
550-
	if @PositorUID is null
550+
551-
	raiserror('The referenced @PositorUID does not exist', 10, 1);
551+
552
order by [DereferencingSetUID], [PositorUID], [AppearanceTime] desc, [AssertionTime] desc;
553-
	-- now store the assertion
553+
554-
	insert into [Assertion] (
554+
555-
		[AssertionUID], 
555+
556-
		[PositorUID], 
556+
557-
		[PositUID], 
557+
558-
		[Reliability], 
558+
559
A body of information is said to be symmetric iff the assertions
560
!(P, p, −α, T) and !(P, ̄p, α, T) are equivalent for a posit p and its opposite ̄p.
561-
	select  
561+
562-
		@AssertionUID,
562+
563-
		@PositorUID,
563+
564-
		@PositUID,
564+
565-
		Posit.value('@Reliability', 'decimal(3,2)') as [AppearanceTime],
565+
566-
		Posit.value('@AssertionTime', 'datetime') as [AppearanceTime]
566+
567-
	from @assertion.nodes(
567+
568-
		'/Assertion[1]'
568+
569-
	) as T(Posit) 
569+
570
for the same dereferencing set satisfy the inequality:
571-
	-- and we are done, so finally set the output variable
571+
572-
	set @assertion = (
572+
573-
		select [AssertionXML] from [v_Assertion] where [AssertionUID] = @AssertionUID
573+
574-
	);
574+
575-
end
575+
576
The fact that we can talk about contradictions relies on the assumption that our body
577
of information is symmetric. When a body of information is also bounded it is possible to 
578
transform all information into canonical form (negated values like "not red" are instead
579-
-- first create a few things (and positors), and relate them to a name using "has name"
579+
580-
declare @assertion1 xml = '
580+
581-
	<Assertion PositorUID="A" Reliability="1.00" AssertionTime="2018-12-15 00:00">
581+
582-
	  <Posit AppearanceTime="1972-08-20 15:30">
582+
583-
		<DereferencingSet>
583+
584-
		  <Appearance ThingUID="A" Role="has name" />
584+
585-
		</DereferencingSet>
585+
586-
		<Value>Archie</Value>
586+
587-
	  </Posit>
587+
588-
	</Assertion>
588+
		[AppearanceTime], [AssertionTime]
589-
';
589+
	from 
590-
exec Assert @assertion1 OUTPUT;
590+
		(select distinct [AppearanceTime] from Posit) p
591
	cross join
592-
-- the stored assertion is returned (in case we need any of the UID:s for later)
592+
		(select distinct [AssertionTime] from Assertion) a
593-
select @assertion1; 
593+
594-
-- but we can also look at it using the view
594+
595-
select * from [v_Assertion];
595+
596
	case 
597-
declare @assertion2 xml = '
597+
598-
	<Assertion PositorUID="B" Reliability="1.00" AssertionTime="2018-12-15 00:00">
598+
599-
	  <Posit AppearanceTime="1972-02-13 08:00">
599+
600-
		<DereferencingSet>
600+
601-
		  <Appearance ThingUID="B" Role="has name" />
601+
602-
		</DereferencingSet>
602+
603-
		<Value>Bella</Value>
603+
604-
	  </Posit>
604+
605-
	</Assertion>
605+
606-
';
606+
607-
exec Assert @assertion2 OUTPUT;
607+
608
		bitemporalTimepoints t
609-
declare @assertion3 xml = '
609+
610-
	<Assertion PositorUID="M" Reliability="1.00" AssertionTime="2018-12-15 00:00">
610+
611-
	  <Posit AppearanceTime="1945-10-17 12:00">
611+
612-
		<DereferencingSet>
612+
613-
		  <Appearance ThingUID="M" Role="has name" />
613+
614-
		</DereferencingSet>
614+
615-
		<Value>Modeler</Value>
615+
616-
	  </Posit>
616+
617-
	</Assertion>
617+
618-
';
618+
619-
exec Assert @assertion3 OUTPUT;
619+
620
select * from [Check_for_Contradictions];
621-
declare @assertion4 xml = '
621+
622-
	<Assertion PositorUID="S" Reliability="1.00" AssertionTime="2018-12-15 00:00">
622+
-- which information is in effect at 12 and 13 given latest assertions?
623-
	  <Posit AppearanceTime="2018-12-15">
623+
select * from [Information_in_Effect]('2018-12-01 12:00', getdate())
624-
		<DereferencingSet>
624+
625-
		  <Appearance ThingUID="S" Role="has name" />
625+
select * from [Information_in_Effect]('2018-12-01 13:00', getdate())
626-
		</DereferencingSet>
626+
627-
		<Value>Script</Value>
627+
628-
	  </Posit>
628+
-- Bella realizes she will remain forever contradictory about 12:00, so she makes another assertion
629-
	</Assertion>
629+
drop table if exists #Assertion6;
630-
';
630+
create table #Assertion6([UID] uniqueidentifier not null primary key);
631-
exec Assert @assertion4 OUTPUT;
631+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion6 values (DEFAULT);
632
633-
declare @assertion5 xml = '
633+
634-
	<Assertion PositorUID="D" Reliability="1.00" AssertionTime="2018-12-15 00:00">
634+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
635-
	  <Posit AppearanceTime="2001-01-01 01:00">
635+
select a.[UID], Bella.[UID], p.[UID], 0.95, '2018-12-13 15:40'
636-
		<DereferencingSet>
636+
from #Assertion6 a, #B Bella, #Posit1 p;
637-
		  <Appearance ThingUID="D" Role="has name" />
637+
638-
		</DereferencingSet>
638+
-- which information is in effect at 12 and 13 given latest assertions?
639-
		<Value>Disser</Value>
639+
select * from [Information_in_Effect]('2018-12-01 12:00', getdate())
640-
	  </Posit>
640+
641-
	</Assertion>
641+
select * from [Information_in_Effect]('2018-12-01 13:00', getdate())
642-
';
642+
643-
exec Assert @assertion5 OUTPUT;
643+
644
-- have contradictory assertions been made?
645-
-- there should now be five assertions
645+
646-
select * from [v_Assertion];
646+
647
-- the Disagreer is now changing it's mind and retracts the previous statement
648-
-- first we will let Bella assert a few things about Archie
648+
drop table if exists #Assertion7;
649-
declare @ArchieUID6 varchar(555) = (
649+
create table #Assertion7([UID] uniqueidentifier not null primary key);
650-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
650+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion7 values (DEFAULT);
651-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
651+
652
-- a retraction has reliability = 0
653-
declare @BellaUID6 varchar(555) = (
653+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
654-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
654+
select a.[UID], Disagreer.[UID], p.[UID], 0, '2018-12-13 15:40'
655-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
655+
from #Assertion7 a, #D Disagreer, #Posit2 p;
656
657-
declare @assertion6 xml = '
657+
658-
	<Assertion PositorUID="' + @BellaUID6 + '" Reliability="1.00" AssertionTime="2018-12-13 15:30">
658+
659-
	  <Posit AppearanceTime="2018-12-01 12:00">
659+
660-
		<DereferencingSet>
660+
661-
		  <Appearance ThingUID="' + @ArchieUID6 + '" Role="has beard" />
661+
662-
		</DereferencingSet>
662+
663-
		<Value>fluffy red</Value>
663+
664-
	  </Posit>
664+
665-
	</Assertion>
665+
drop table if exists #Posit4;
666-
';
666+
create table #Posit4([UID] uniqueidentifier not null primary key);
667-
exec Assert @assertion6 OUTPUT;
667+
insert into [Thing]([UID]) output inserted.[UID] into #Posit4 values (DEFAULT);
668
669-
-- there should now be a new assertion
669+
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
670-
select * from [v_Assertion] where [Value] = 'fluffy red';
670+
select p.[UID], s.[UID], 'shaved clean', '2018-12-01 14:00'
671
from #Posit4 p, #DereferencingSet1 s;
672-
-- let the Disser have a different opinion
672+
673-
declare @ArchieUID7 varchar(555) = (
673+
drop table if exists #Assertion8;
674-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
674+
create table #Assertion8([UID] uniqueidentifier not null primary key);
675-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
675+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion8 values (DEFAULT);
676
677-
declare @DisserUID7 varchar(555) = (
677+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
678-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
678+
select a.[UID], Bella.[UID], p.[UID], 1, '2018-12-13 15:45'
679-
	cross apply AssertionXML.nodes('//*[Value = "Disser"]//*[@Role = "has name"]') as T(Appearance)
679+
from #Assertion8 a, #B Bella, #Posit4 p;
680
681-
declare @assertion7 xml = '
681+
682-
	<Assertion PositorUID="' + @DisserUID7 + '" Reliability="1.00" AssertionTime="2018-12-13 15:30">
682+
683-
	  <Posit AppearanceTime="2018-12-01 12:00">
683+
684-
		<DereferencingSet>
684+
685-
		  <Appearance ThingUID="' + @ArchieUID7 + '" Role="has beard" />
685+
686-
		</DereferencingSet>
686+
687-
		<Value>shaved clean</Value>
687+
688-
	  </Posit>
688+
689-
	</Assertion>
689+
690-
';
690+
691-
exec Assert @assertion7 OUTPUT;
691+
692
693-
-- there should now be two assertions
693+
694-
-- where Bella and the Disagreer have conflicting views of Archie's beard
694+
drop table if exists #Assertion9;
695-
select * from [v_Assertion] where [Value] in ('fluffy red', 'shaved clean');
695+
create table #Assertion9([UID] uniqueidentifier not null primary key);
696
insert into [Thing]([UID]) output inserted.[UID] into #Assertion9 values (DEFAULT);
697-
-- let the Disser further oppose to what Bella stated
697+
698-
declare @ArchieUID8 varchar(555) = (
698+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
699-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
699+
select a.[UID], Bella.[UID], p.[UID], 1, '2018-12-13 15:50'
700-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
700+
from #Assertion9 a, #B Bella, #Posit4 p;
701
702-
declare @DisserUID8 varchar(555) = (
702+
703-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
703+
704-
	cross apply AssertionXML.nodes('//*[Value = "Disser"]//*[@Role = "has name"]') as T(Appearance)
704+
705
706-
declare @assertion8 xml = '
706+
707-
	<Assertion PositorUID="' + @DisserUID8 + '" Reliability="-1.00" AssertionTime="2018-12-13 15:35">
707+
708-
	  <Posit AppearanceTime="2018-12-01 12:00">
708+
709-
		<DereferencingSet>
709+
710-
		  <Appearance ThingUID="' + @ArchieUID8 + '" Role="has beard" />
710+
711-
		</DereferencingSet>
711+
712-
		<Value>fluffy red</Value>
712+
713-
	  </Posit>
713+
714-
	</Assertion>
714+
715-
';
715+
716-
exec Assert @assertion8 OUTPUT;
716+
717
-- The good thing about posits, assertions, and so on being "things" in themselves
718-
-- so Bella and the Disser have opposing views of the posit stating it is fluffy red
718+
719-
select * from [v_Assertion] where [Value] in ('fluffy red', 'shaved clean');
719+
720
721
-- let the Script positor assert when what we have done so far was recorded in 
722-
declare @ArchieUID9 varchar(555) = (
722+
723-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
723+
724-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
724+
-- we now have 21 things
725
select * from [Thing];
726-
declare @BellaUID9 varchar(555) = (
726+
727-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
727+
-- create another role thing 
728-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
728+
drop table if exists #Role2;
729
create table #Role2([UID] uniqueidentifier not null primary key); 
730-
declare @assertion9 xml = '
730+
insert into [Thing]([UID]) output inserted.[UID] into #Role2 values (DEFAULT);
731-
	<Assertion PositorUID="' + @BellaUID9 + '" Reliability="0.05" AssertionTime="2018-12-13 15:35">
731+
732-
	  <Posit AppearanceTime="2018-12-01 12:00">
732+
-- create a new role
733-
		<DereferencingSet>
733+
insert into [Role]([RoleUID], [Role]) 
734-
		  <Appearance ThingUID="' + @ArchieUID9 + '" Role="has beard" />
734+
select [UID], 'was recorded at' 
735-
		</DereferencingSet>
735+
from #Role2;
736-
		<Value>shaved clean</Value>
736+
737-
	  </Posit>
737+
-- check what the role looks like
738-
	</Assertion>
738+
select * from [Role];
739-
';
739+
740-
exec Assert @assertion9 OUTPUT;
740+
-- create an appearance thing for every thing we have created
741
drop table if exists #Appearance2;
742
create table #Appearance2([UID] uniqueidentifier not null primary key); 
743-
select * from [v_Assertion] where [Value] in ('fluffy red', 'shaved clean')
743+
merge [Thing] t 
744
using [Thing] src on 1 = 0 -- make sure everything is "not matched" below
745
when not matched then insert ([UID]) values (DEFAULT)
746-
-- she is sure Archie was shaved clean later though (a real change occured between 12 and 13)
746+
output inserted.[UID] into #Appearance2;
747-
declare @ArchieUID10 varchar(555) = (
747+
748-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
748+
-- create an equal number of appearances 
749-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
749+
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
750
select app.[UID], t.[UID], r.[RoleUID] 
751-
declare @BellaUID10 varchar(555) = (
751+
from (select [UID], row_number() over (order by [UID]) as _row from #Appearance2) app
752-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
752+
join (select [UID], row_number() over (order by [UID]) as _row from [Thing]) t 
753-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
753+
on t._row = app._row
754
cross apply (select [RoleUID] from [Role] where [Role] = 'was recorded at') r;
755-
declare @assertion10 xml = '
755+
756-
	<Assertion PositorUID="' + @BellaUID10 + '" Reliability="1.00" AssertionTime="2018-12-13 15:35">
756+
-- we now have 23 appearances
757-
	  <Posit AppearanceTime="2018-12-01 13:00">
757+
select * from [Appearance];
758-
		<DereferencingSet>
758+
759-
		  <Appearance ThingUID="' + @ArchieUID10 + '" Role="has beard" />
759+
-- create 22 dereferencing set things
760-
		</DereferencingSet>
760+
drop table if exists #DereferencingSet2;
761-
		<Value>shaved clean</Value>
761+
create table #DereferencingSet2([UID] uniqueidentifier not null primary key); 
762-
	  </Posit>
762+
merge [Thing] t 
763-
	</Assertion>
763+
using #Appearance2 src on 1 = 0 -- make sure everything is "not matched" below
764-
';
764+
when not matched then insert ([UID]) values (DEFAULT)
765-
exec Assert @assertion10 OUTPUT;
765+
output inserted.[UID] into #DereferencingSet2;
766
767
-- create 22 dereferencing sets
768-
select * from [v_Assertion] where [Value] in ('fluffy red', 'shaved clean')
768+
insert into [DereferencingSet]([DereferencingSetUID]) 
769
select [UID]
770
from #DereferencingSet2;
771
772
-- add the appearances to the dereferencing sets
773
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
774
select s.[UID], app.[UID]
775
from (select [UID], row_number() over (order by [UID]) as _row from #DereferencingSet2) s
776
join (select [UID], row_number() over (order by [UID]) as _row from #Appearance2) app
777
on s._row = app._row;
778
779
-- create 22 posit things
780
drop table if exists #Posit5;
781
create table #Posit5([UID] uniqueidentifier not null primary key);
782
merge [Thing] t 
783
using #DereferencingSet2 src on 1 = 0 -- make sure everything is "not matched" below
784
when not matched then insert ([UID]) values (DEFAULT)
785
output inserted.[UID] into #Posit5;
786
787
-- create 22 posits (with the limitation that the date needs to be converted to a string)
788
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
789
select p.[UID], s.[UID], cast(getdate() as varchar(max)), getdate()
790
from (select [UID], row_number() over (order by [UID]) as _row from #Posit5) p
791
join (select [UID], row_number() over (order by [UID]) as _row from #DereferencingSet2) s
792
on p._row = s._row;
793
794
-- we now have 26 posits, the last 22 of which intends to capture metadata
795
select * from [v_Posit];
796
797
-- finally let the Script positor assert these
798
drop table if exists #Assertion10;
799
create table #Assertion10([UID] uniqueidentifier not null primary key);
800-
	select *
800+
merge [Thing] t 
801-
	  from [v_Assertion]
801+
using #Posit5 src on 1 = 0 -- make sure everything is "not matched" below
802-
	 where [AppearanceTime] <= @appearanceTime
802+
when not matched then insert ([UID]) values (DEFAULT)
803-
	   and [AssertionTime]  <= @assertionTime
803+
output inserted.[UID] into #Assertion10;
804
805
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
806-
	select a.*
806+
select a.[UID], Script.[UID], p.[UID], 1, getdate()
807-
	  from A1 a
807+
from (select [UID], row_number() over (order by [UID]) as _row from #Assertion10) a
808-
	 where a.[Reliability] <> 0
808+
join (select [UID], row_number() over (order by [UID]) as _row from #Posit5) p
809-
	   and a.[AppearanceTime] = (
809+
on a._row = p._row
810-
		   select max(s.[AppearanceTime])
810+
cross apply #S Script;
811-
			 from A1 s
811+
812-
			where s.[PositorUID] = a.[PositorUID]
812+
-- there are now 31 assertions
813-
			  and s.[DereferencingSetUID] = a.[DereferencingSetUID]
813+
814-
	   )
814+
815-
	   and not exists (
815+
816-
		   select x.[AssertionUID]
816+
817-
		     from A1 x
817+
818-
		    where x.[PositorUID] = a.[PositorUID]
818+
819-
		      and x.[PositUID] = a.[PositUID]
819+
820-
		      and x.[Reliability] = 0
820+
-- finding all (current) metadata can be done by a condition on our Script positor
821-
		      and x.[AssertionTime] between a.AssertionTime and @assertionTime
821+
822-
	   )
822+
where [PositorUID] = (select top 1 [UID] from #S)
823
order by [DereferencingSetUID], [PositorUID], [AppearanceTime] desc, [AssertionTime] desc;
824-
select a.*
824+
825-
  from A2 a
825+
826-
 where a.[AssertionTime] = (
826+
-- we will start by marrying Archie and Bella
827-
	   select max(s.[AssertionTime])
827+
828-
		 from A2 s
828+
-- create a few new role things
829-
		where s.[PositorUID] = a.[PositorUID]
829+
drop table if exists #Role3;
830-
		  and s.[DereferencingSetUID] = a.[DereferencingSetUID]
830+
create table #Role3([UID] uniqueidentifier not null primary key); 
831-
		  and s.[Value] = a.[Value]
831+
insert into [Thing]([UID]) output inserted.[UID] into #Role3 values (DEFAULT);
832-
)		
832+
drop table if exists #Role4;
833
create table #Role4([UID] uniqueidentifier not null primary key); 
834
insert into [Thing]([UID]) output inserted.[UID] into #Role4 values (DEFAULT);
835
drop table if exists #Role5;
836
create table #Role5([UID] uniqueidentifier not null primary key); 
837
insert into [Thing]([UID]) output inserted.[UID] into #Role5 values (DEFAULT);
838
839
-- create the new roles
840
insert into [Role]([RoleUID], [Role]) 
841
select [UID], 'husband' 
842
from #Role3;
843
insert into [Role]([RoleUID], [Role]) 
844
select [UID], 'wife' 
845
from #Role4;
846
insert into [Role]([RoleUID], [Role]) 
847
select [UID], 'church' 
848
from #Role5;
849
850
-- what roles have got now?
851
select * from [Role];
852
853
-- we will need a church thing
854
drop table if exists #C;
855
create table #C([UID] uniqueidentifier not null primary key); -- Church
856
857
-- create the Church thing
858
insert into [Thing]([UID]) output inserted.[UID] into #C values (DEFAULT);
859
860
-- we also need three appearance things
861
drop table if exists #Appearance3;
862
create table #Appearance3([UID] uniqueidentifier not null primary key); 
863
insert into [Thing]([UID]) output inserted.[UID] into #Appearance3 values (DEFAULT);
864
drop table if exists #Appearance4;
865
create table #Appearance4([UID] uniqueidentifier not null primary key); 
866
insert into [Thing]([UID]) output inserted.[UID] into #Appearance4 values (DEFAULT);
867
drop table if exists #Appearance5;
868
create table #Appearance5([UID] uniqueidentifier not null primary key); 
869
insert into [Thing]([UID]) output inserted.[UID] into #Appearance5 values (DEFAULT);
870
871
-- create three appearances
872
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
873
select app.[UID], Archie.[UID], r.[RoleUID] 
874
from [Role] r, #Appearance3 app, #A Archie 
875
where r.[Role] = 'husband';
876
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
877
select app.[UID], Bella.[UID], r.[RoleUID] 
878-
	select [AppearanceTime], [AssertionTime]
878+
from [Role] r, #Appearance4 app, #B Bella 
879-
	from (select distinct [AppearanceTime] from Posit) p
879+
where r.[Role] = 'wife';
880-
	cross join (select distinct [AssertionTime] from Assertion) a
880+
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
881
select app.[UID], Church.[UID], r.[RoleUID] 
882
from [Role] r, #Appearance5 app, #C Church
883
where r.[Role] = 'church';
884
885
-- create a dereferencing set thing
886
drop table if exists #DereferencingSet3;
887
create table #DereferencingSet3([UID] uniqueidentifier not null primary key); 
888
insert into [Thing]([UID]) output inserted.[UID] into #DereferencingSet3 values (DEFAULT);
889
890
-- create a dereferencing set
891
insert into [DereferencingSet]([DereferencingSetUID]) 
892
select [UID]
893
from #DereferencingSet3;
894
895
-- add the created appearances to the (same) dereferencing set
896
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
897
select s.[UID], app.[UID]
898
from #DereferencingSet3 s, #Appearance3 app;
899
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
900
select s.[UID], app.[UID]
901
from #DereferencingSet3 s, #Appearance4 app;
902
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
903
select s.[UID], app.[UID]
904
from #DereferencingSet3 s, #Appearance5 app;
905
906
-- create a posit thing
907
drop table if exists #Posit6;
908
create table #Posit6([UID] uniqueidentifier not null primary key);
909-
-- Bella is contradictory for the appearance time between 12 and 13 for assertion time 15:35 and onwards
909+
insert into [Thing]([UID]) output inserted.[UID] into #Posit6 values (DEFAULT);
910-
-- so with our current knowledge she has made contradictory statements
910+
911
-- create a posit
912-
-- Bella realizes she will remain forever contradictory unless she makes another assertion
912+
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
913
select p.[UID], s.[UID], 'married', '2004-06-19 15:00'
914-
declare @ArchieUID11 varchar(555) = (
914+
from #Posit6 p, #DereferencingSet3 s;
915-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
915+
916-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
916+
-- now the posit is complete (note that the set has three members now)
917
select * from [v_Posit] 
918-
declare @BellaUID11 varchar(555) = (
918+
where [DereferencingSetUID] = (select top 1 [UID] from #DereferencingSet3);
919-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
919+
920-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
920+
-- let Bella assert this, so first create an assertion thing
921
drop table if exists #Assertion11;
922-
declare @assertion11 xml = '
922+
create table #Assertion11([UID] uniqueidentifier not null primary key);
923-
	<Assertion PositorUID="' + @BellaUID11 + '" Reliability="0.95" AssertionTime="2018-12-13 15:40">
923+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion11 values (DEFAULT);
924-
	  <Posit AppearanceTime="2018-12-01 12:00">
924+
925-
		<DereferencingSet>
925+
-- create an assertion
926-
		  <Appearance ThingUID="' + @ArchieUID11 + '" Role="has beard" />
926+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
927-
		</DereferencingSet>
927+
select a.[UID], Bella.[UID], p.[UID], 1, '2018-12-13 15:55'
928-
		<Value>fluffy red</Value>
928+
from #Assertion11 a, #B Bella, #Posit6 p;
929-
	  </Posit>
929+
930-
	</Assertion>
930+
931-
';
931+
932-
exec Assert @assertion11 OUTPUT;
932+
where [DereferencingSetUID] = (select top 1 [UID] from #DereferencingSet3)
933
order by [DereferencingSetUID], [PositorUID], [AppearanceTime] desc, [AssertionTime] desc;
934-
-- which information is in effect at 12 and 13 given that assertion
934+
935
-- let them divorce a while later (using the same dereferencing set)
936
-- create a posit thing
937
drop table if exists #Posit7;
938
create table #Posit7([UID] uniqueidentifier not null primary key);
939-
-- now the situation looks better for Bella between 12 and 13
939+
insert into [Thing]([UID]) output inserted.[UID] into #Posit7 values (DEFAULT);
940
941
-- create a posit
942
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
943-
-- Bella is contradictory for the appearance time between 12 and 13 but now only for 
943+
select p.[UID], s.[UID], 'divorced', '2010-01-31 10:00'
944-
-- assertion time between 15:35 and 15:45
944+
from #Posit7 p, #DereferencingSet3 s;
945
946
-- the state of this dereferencing set has transitioned from 'married' to 'divorced'
947
select * from [v_Posit] 
948-
declare @ArchieUID12 varchar(555) = (
948+
where [DereferencingSetUID] = (select top 1 [UID] from #DereferencingSet3);
949-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
949+
950-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
950+
-- let Bella assert this as well, so first create an assertion thing
951
drop table if exists #Assertion12;
952-
declare @DisserUID12 varchar(555) = (
952+
create table #Assertion12([UID] uniqueidentifier not null primary key);
953-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
953+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion12 values (DEFAULT);
954-
	cross apply AssertionXML.nodes('//*[Value = "Disser"]//*[@Role = "has name"]') as T(Appearance)
954+
955
-- create an assertion
956-
declare @assertion12 xml = '
956+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
957-
	<Assertion PositorUID="' + @DisserUID12 + '" Reliability="0" AssertionTime="2018-12-13 15:40">
957+
select a.[UID], Bella.[UID], p.[UID], 1, '2018-12-13 15:55'
958-
	  <Posit AppearanceTime="2018-12-01 12:00">
958+
from #Assertion12 a, #B Bella, #Posit7 p;
959-
		<DereferencingSet>
959+
960-
		  <Appearance ThingUID="' + @ArchieUID12 + '" Role="has beard" />
960+
-- now Bella has asserted the divorce
961-
		</DereferencingSet>
961+
962-
		<Value>shaved clean</Value>
962+
where [DereferencingSetUID] = (select top 1 [UID] from #DereferencingSet3)
963-
	  </Posit>
963+
964-
	</Assertion>
964+
965-
';
965+
966-
exec Assert @assertion12 OUTPUT;
966+
967
968
-- first the Disagreer must appear as husband
969
drop table if exists #Appearance6;
970
create table #Appearance6([UID] uniqueidentifier not null primary key); 
971
insert into [Thing]([UID]) output inserted.[UID] into #Appearance6 values (DEFAULT);
972
973-
-- the Disser is now only saying it's not fluffy red
973+
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
974
select app.[UID], Disagreer.[UID], r.[RoleUID] 
975
from [Role] r, #Appearance6 app, #D Disagreer 
976-
declare @ArchieUID13 varchar(555) = (
976+
where r.[Role] = 'husband';
977-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
977+
978-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
978+
-- create a dereferencing set thing
979
drop table if exists #DereferencingSet4;
980-
declare @BellaUID13 varchar(555) = (
980+
create table #DereferencingSet4([UID] uniqueidentifier not null primary key); 
981-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
981+
insert into [Thing]([UID]) output inserted.[UID] into #DereferencingSet4 values (DEFAULT);
982-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
982+
983
-- create a dereferencing set
984-
declare @assertion13 xml = '
984+
insert into [DereferencingSet]([DereferencingSetUID]) 
985-
	<Assertion PositorUID="' + @BellaUID13 + '" Reliability="1.00" AssertionTime="2018-12-13 15:45">
985+
select [UID]
986-
	  <Posit AppearanceTime="2018-12-01 14:00">
986+
from #DereferencingSet4;
987-
		<DereferencingSet>
987+
988-
		  <Appearance ThingUID="' + @ArchieUID13 + '" Role="has beard" />
988+
-- add the created appearances to the dereferencing set (with only two members)
989-
		</DereferencingSet>
989+
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
990-
		<Value>shaved clean</Value>
990+
select s.[UID], app.[UID]
991-
	  </Posit>
991+
from #DereferencingSet4 s, #Appearance6 app;
992-
	</Assertion>
992+
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
993-
';
993+
select s.[UID], app.[UID]
994-
exec Assert @assertion13 OUTPUT;
994+
from #DereferencingSet4 s, #Appearance4 app;
995
996
-- create a posit thing
997-
select * from [v_Assertion] where [Value] in ('fluffy red', 'shaved clean')
997+
drop table if exists #Posit8;
998
create table #Posit8([UID] uniqueidentifier not null primary key);
999
insert into [Thing]([UID]) output inserted.[UID] into #Posit8 values (DEFAULT);
1000
1001
-- create a posit
1002
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
1003
select p.[UID], s.[UID], 'married', '2011-11-11 11:11'
1004
from #Posit8 p, #DereferencingSet4 s;
1005
1006
-- let Bella assert this as well, so first create an assertion thing
1007
drop table if exists #Assertion13;
1008
create table #Assertion13([UID] uniqueidentifier not null primary key);
1009-
declare @ArchieUID14 varchar(555) = (
1009+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion13 values (DEFAULT);
1010-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1010+
1011-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
1011+
-- create an assertion
1012
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
1013-
declare @BellaUID14 varchar(555) = (
1013+
select a.[UID], Bella.[UID], p.[UID], 1, '2018-12-13 15:55'
1014-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1014+
from #Assertion13 a, #B Bella, #Posit8 p;
1015-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1015+
1016
-- now Bella has asserted her second marriage
1017-
declare @assertion14 xml = '
1017+
-- we can find this from finding every assertion in which Bella has appeared in the wife role
1018-
	<Assertion PositorUID="' + @BellaUID14 + '" Reliability="1.00" AssertionTime="2018-12-13 15:50">
1018+
1019-
	  <Posit AppearanceTime="2018-12-01 14:00">
1019+
-- note: it is also possible to achieve the same result using joins instead of the XML query
1020-
		<DereferencingSet>
1020+
select a.* from [v_Assertion] a cross apply #B Bella
1021-
		  <Appearance ThingUID="' + @ArchieUID14 + '" Role="has beard" />
1021+
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@UID = sql:column("Bella.UID") and @Role = "wife"]') = 1
1022-
		</DereferencingSet>
1022+
1023-
		<Value>shaved clean</Value>
1023+
1024-
	  </Posit>
1024+
1025-
	</Assertion>
1025+
1026-
';
1026+
drop table if exists #Assertion14;
1027-
exec Assert @assertion14 OUTPUT;
1027+
create table #Assertion14([UID] uniqueidentifier not null primary key);
1028
insert into [Thing]([UID]) output inserted.[UID] into #Assertion14 values (DEFAULT);
1029
1030-
select * from [v_Assertion] where [Value] in ('fluffy red', 'shaved clean')
1030+
-- create an assertion (that is a retraction since Reliability = 0)
1031
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
1032
select a.[UID], Bella.[UID], p.[UID], 0, '2018-12-13 16:00'
1033
from #Assertion14 a, #B Bella, #Posit8 p;
1034
1035
-- in the view of all assertions the retraction is now visible
1036
select a.* from [v_Assertion] a cross apply #B Bella
1037
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@UID = sql:column("Bella.UID") and @Role = "wife"]') = 1
1038
order by [PositorUID], [AppearanceTime] desc, [AssertionTime] desc;
1039
1040
-- which means that the latest information we have is that Bella is divorced
1041
select a.* from [Information_in_Effect](getdate(), getdate()) a cross apply #B Bella
1042
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@UID = sql:column("Bella.UID") and @Role = "wife"]') = 1
1043
order by [PositorUID], [AppearanceTime] desc, [AssertionTime] desc;
1044
1045
-- so Bella needs to assert a different posit, with the correct appearance time
1046
drop table if exists #Posit9;
1047
create table #Posit9([UID] uniqueidentifier not null primary key);
1048
insert into [Thing]([UID]) output inserted.[UID] into #Posit9 values (DEFAULT);
1049
1050
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
1051-
-- we now have 42 things that we want to create metadata for 
1051+
select p.[UID], s.[UID], 'married', '2012-12-12 12:12'
1052
from #Posit9 p, #DereferencingSet4 s;
1053
1054-
declare @ScriptUID15 varchar(555) = (
1054+
drop table if exists #Assertion15;
1055-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1055+
create table #Assertion15([UID] uniqueidentifier not null primary key);
1056-
	cross apply AssertionXML.nodes('//*[Value = "Script"]//*[@Role = "has name"]') as T(Appearance)
1056+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion15 values (DEFAULT);
1057
1058
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
1059-
declare thing cursor static for (select [UID] from [Thing]);
1059+
select a.[UID], Bella.[UID], p.[UID], 1, '2018-12-13 16:00'
1060-
open thing;
1060+
from #Assertion15 a, #B Bella, #Posit9 p;
1061
1062-
declare @ThingUID15 varchar(555);
1062+
1063-
fetch next from thing into @ThingUID15;
1063+
select a.* from [v_Assertion] a cross apply #B Bella
1064
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@UID = sql:column("Bella.UID") and @Role = "wife"]') = 1
1065-
declare @now char(19) = CONVERT(varchar(19), getdate(), 121);
1065+
1066
1067-
while(@@FETCH_STATUS = 0)
1067+
1068-
begin
1068+
1069-
	declare @assertion15 xml = '
1069+
select a.* from [Information_in_Effect](getdate(), getdate()) a cross apply #B Bella
1070-
		<Assertion PositorUID="' + @ScriptUID15 + '" Reliability="1.00" AssertionTime="' + @now + '">
1070+
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@UID = sql:column("Bella.UID") and @Role = "wife"]') = 1
1071-
		  <Posit AppearanceTime="' + @now + '">
1071+
1072-
			<DereferencingSet>
1072+
1073-
			  <Appearance ThingUID="' + @ThingUID15 + '" Role="was recorded at" />
1073+
1074-
			</DereferencingSet>
1074+
1075-
			<Value>' + @now + '</Value>
1075+
1076-
		  </Posit>
1076+
1077-
		</Assertion>
1077+
1078-
	';
1078+
1079-
	exec Assert @assertion15 OUTPUT;
1079+
1080
of a class through the string c and associates the unique
1081-
	fetch next from thing into @ThingUID15;
1081+
1082-
end
1082+
1083
pM = [{(i, thing),(C, class)}, v, t].
1084-
close thing;
1084+
1085-
deallocate thing;
1085+
1086
It is time for the Modeler to step in and tell us what some of our things are.
1087-
-- now there are 42 assertions from which we can tell when the data entered the database
1087+
1088-
select * from [v_Assertion] where isdate([Value]) = 1
1088+
-- we need three new roles in order to create a model
1089
drop table if exists #Role6;
1090
create table #Role6([UID] uniqueidentifier not null primary key); 
1091
insert into [Thing]([UID]) output inserted.[UID] into #Role6 values (DEFAULT);
1092
drop table if exists #Role7;
1093
create table #Role7([UID] uniqueidentifier not null primary key); 
1094
insert into [Thing]([UID]) output inserted.[UID] into #Role7 values (DEFAULT);
1095-
-- but it is in effect now
1095+
drop table if exists #Role8;
1096-
select * from [Information_in_Effect](getdate(), getdate()) 
1096+
create table #Role8([UID] uniqueidentifier not null primary key); 
1097
insert into [Thing]([UID]) output inserted.[UID] into #Role8 values (DEFAULT);
1098
1099
-- create the new roles
1100-
-- we will start by marrying Archie and Bella in the Notre-Dame
1100+
insert into [Role]([RoleUID], [Role]) 
1101-
-- so we first need the Notre-Dame thing
1101+
select [UID], 'is class' 
1102-
declare @assertion16 xml = '
1102+
from #Role6;
1103-
	<Assertion PositorUID="NDame" Reliability="1.00" AssertionTime="2018-12-15 00:00">
1103+
insert into [Role]([RoleUID], [Role]) 
1104-
	  <Posit AppearanceTime="1753-01-01">
1104+
select [UID], 'thing' 
1105-
		<DereferencingSet>
1105+
from #Role7;
1106-
		  <Appearance ThingUID="NDame" Role="has name" />
1106+
insert into [Role]([RoleUID], [Role]) 
1107-
		</DereferencingSet>
1107+
select [UID], 'class' 
1108-
		<Value>Notre-Dame de Paris</Value>
1108+
from #Role8;
1109-
	  </Posit>
1109+
1110-
	</Assertion>
1110+
-- what roles have got now?
1111-
';
1111+
select * from [Role] order by RoleUID;
1112-
exec Assert @assertion16 OUTPUT;
1112+
1113
-- create two class things
1114-
-- we need the UID:s
1114+
drop table if exists #Class1;
1115-
declare @ArchieUID17 varchar(555) = (
1115+
create table #Class1([UID] uniqueidentifier not null primary key); 
1116-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1116+
insert into [Thing]([UID]) output inserted.[UID] into #Class1 values (DEFAULT);
1117-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
1117+
drop table if exists #Class2;
1118
create table #Class2([UID] uniqueidentifier not null primary key); 
1119-
declare @BellaUID17 varchar(555) = (
1119+
insert into [Thing]([UID]) output inserted.[UID] into #Class2 values (DEFAULT);
1120-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1120+
1121-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1121+
-- the classes need names, so first they need to appear with the "is class" role
1122
drop table if exists #Appearance7;
1123-
declare @NDameUID17 varchar(555) = (
1123+
create table #Appearance7([UID] uniqueidentifier not null primary key); 
1124-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1124+
insert into [Thing]([UID]) output inserted.[UID] into #Appearance7 values (DEFAULT);
1125-
	cross apply AssertionXML.nodes('//*[Value = "Notre-Dame de Paris"]//*[@Role = "has name"]') as T(Appearance)
1125+
drop table if exists #Appearance8;
1126
create table #Appearance8([UID] uniqueidentifier not null primary key); 
1127-
declare @assertion17 xml = '
1127+
insert into [Thing]([UID]) output inserted.[UID] into #Appearance8 values (DEFAULT);
1128-
	<Assertion PositorUID="' + @BellaUID17 + '" Reliability="1.00" AssertionTime="2018-12-13 15:55">
1128+
1129-
	  <Posit AppearanceTime="2004-06-19 15:00">
1129+
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
1130-
		<DereferencingSet>
1130+
select app.[UID], c.[UID], r.[RoleUID] 
1131-
		  <Appearance ThingUID="' + @ArchieUID17 + '" Role="husband" />
1131+
from [Role] r, #Appearance7 app, #Class1 c 
1132-
		  <Appearance ThingUID="' + @BellaUID17 + '" Role="wife" />
1132+
where r.[Role] = 'is class';
1133-
		  <Appearance ThingUID="' + @NDameUID17 + '" Role="church" />
1133+
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
1134-
		</DereferencingSet>
1134+
select app.[UID], c.[UID], r.[RoleUID] 
1135-
		<Value>married</Value>
1135+
from [Role] r, #Appearance8 app, #Class2 c 
1136-
	  </Posit>
1136+
where r.[Role] = 'is class';
1137-
	</Assertion>
1137+
1138-
';
1138+
-- create a dereferencing set thing
1139-
exec Assert @assertion17 OUTPUT;
1139+
drop table if exists #DereferencingSet5;
1140
create table #DereferencingSet5([UID] uniqueidentifier not null primary key); 
1141
insert into [Thing]([UID]) output inserted.[UID] into #DereferencingSet5 values (DEFAULT);
1142-
select * from [v_Assertion] where [Value] in ('married')
1142+
drop table if exists #DereferencingSet6;
1143
create table #DereferencingSet6([UID] uniqueidentifier not null primary key); 
1144
insert into [Thing]([UID]) output inserted.[UID] into #DereferencingSet6 values (DEFAULT);
1145-
-- let them divorce a while later (using the same dereferencing set, so it is a real change)
1145+
1146-
declare @ArchieUID18 varchar(555) = (
1146+
-- create dereferencing sets
1147-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1147+
insert into [DereferencingSet]([DereferencingSetUID]) 
1148-
	cross apply AssertionXML.nodes('//*[Value = "Archie"]//*[@Role = "has name"]') as T(Appearance)
1148+
select [UID]
1149
from #DereferencingSet5;
1150-
declare @BellaUID18 varchar(555) = (
1150+
insert into [DereferencingSet]([DereferencingSetUID]) 
1151-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1151+
select [UID]
1152-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1152+
from #DereferencingSet6;
1153
1154-
declare @NDameUID18 varchar(555) = (
1154+
-- add the created appearances
1155-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1155+
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
1156-
	cross apply AssertionXML.nodes('//*[Value = "Notre-Dame de Paris"]//*[@Role = "has name"]') as T(Appearance)
1156+
select s.[UID], app.[UID]
1157
from #DereferencingSet5 s, #Appearance7 app;
1158-
declare @assertion18 xml = '
1158+
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
1159-
	<Assertion PositorUID="' + @BellaUID18 + '" Reliability="1.00" AssertionTime="2018-12-13 15:55">
1159+
select s.[UID], app.[UID]
1160-
	  <Posit AppearanceTime="2010-01-31 10:00">
1160+
from #DereferencingSet6 s, #Appearance8 app;
1161-
		<DereferencingSet>
1161+
1162-
		  <Appearance ThingUID="' + @ArchieUID18 + '" Role="husband" />
1162+
-- two posit things
1163-
		  <Appearance ThingUID="' + @BellaUID18 + '" Role="wife" />
1163+
drop table if exists #Posit10;
1164-
		  <Appearance ThingUID="' + @NDameUID18 + '" Role="church" />
1164+
create table #Posit10([UID] uniqueidentifier not null primary key);
1165-
		</DereferencingSet>
1165+
insert into [Thing]([UID]) output inserted.[UID] into #Posit10 values (DEFAULT);
1166-
		<Value>divorced</Value>
1166+
drop table if exists #Posit11;
1167-
	  </Posit>
1167+
create table #Posit11([UID] uniqueidentifier not null primary key);
1168-
	</Assertion>
1168+
insert into [Thing]([UID]) output inserted.[UID] into #Posit11 values (DEFAULT);
1169-
';
1169+
1170-
exec Assert @assertion18 OUTPUT;
1170+
-- two posits
1171
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
1172-
-- now Bella has asserted the divorce as well
1172+
select p.[UID], s.[UID], 'Person', '1901-01-01' -- will represent dawn of time
1173-
select * from [v_Assertion] where [Value] in ('married', 'divorced')
1173+
from #Posit10 p, #DereferencingSet5 s;
1174
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
1175
select p.[UID], s.[UID], 'Cathedral', '1901-01-01' -- will represent dawn of time
1176
from #Posit11 p, #DereferencingSet6 s;
1177
1178-
declare @DisserUID19 varchar(555) = (
1178+
-- now, the Modeler must assert these
1179-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1179+
drop table if exists #Assertion16;
1180-
	cross apply AssertionXML.nodes('//*[Value = "Disser"]//*[@Role = "has name"]') as T(Appearance)
1180+
create table #Assertion16([UID] uniqueidentifier not null primary key);
1181
insert into [Thing]([UID]) output inserted.[UID] into #Assertion16 values (DEFAULT);
1182-
declare @BellaUID19 varchar(555) = (
1182+
drop table if exists #Assertion17;
1183-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1183+
create table #Assertion17([UID] uniqueidentifier not null primary key);
1184-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1184+
insert into [Thing]([UID]) output inserted.[UID] into #Assertion17 values (DEFAULT);
1185
1186-
declare @assertion19 xml = '
1186+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
1187-
	<Assertion PositorUID="' + @BellaUID19 + '" Reliability="1.00" AssertionTime="2018-12-13 15:55">
1187+
select a.[UID], Modeler.[UID], p.[UID], 1, '2018-12-01 00:00'
1188-
	  <Posit AppearanceTime="2011-11-11 11:11">
1188+
from #Assertion16 a, #M Modeler, #Posit10 p;
1189-
		<DereferencingSet>
1189+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
1190-
		  <Appearance ThingUID="' + @DisserUID19 + '" Role="husband" />
1190+
select a.[UID], Modeler.[UID], p.[UID], 1, '2018-12-01 00:00'
1191-
		  <Appearance ThingUID="' + @BellaUID19 + '" Role="wife" />
1191+
from #Assertion17 a, #M Modeler, #Posit11 p;
1192-
		</DereferencingSet>
1192+
1193-
		<Value>married</Value>
1193+
1194-
	  </Posit>
1194+
1195-
	</Assertion>
1195+
1196-
';
1196+
1197-
exec Assert @assertion19 OUTPUT;
1197+
1198
-- lot's of work, but two classes are defined
1199-
-- now Bella has asserted her second marriage, but her second marriage took place without a church
1199+
-- they have their own unique identifiers, so many more roles can be added to provide additional
1200-
select * from [v_Assertion] where [Value] in ('married', 'divorced')
1200+
-- information about the classes
1201
1202
-- now it is time to associate some things with the classes
1203-
-- another way to find this is from finding every assertion in which Bella has appeared in the wife role
1203+
-- every such thing needs an appearance with the 'thing' role
1204
drop table if exists #Appearance9;
1205-
declare @BellaUID_Q1 varchar(555) = (
1205+
create table #Appearance9([UID] uniqueidentifier not null primary key); 
1206-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1206+
merge [Thing] t 
1207-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1207+
using (
1208
	select [UID] from #A
1209
	union all
1210-
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@ThingUID = sql:variable("@BellaUID_Q1") and @Role = "wife"]') = 1
1210+
	select [UID] from #B
1211
	union all
1212-
-- the above can be achieved through joins in the underlying model as well
1212+
	select [UID] from #C
1213
	union all
1214
	select [UID] from #M
1215
	union all
1216-
declare @DisserUID20 varchar(555) = (
1216+
	select [UID] from #D
1217-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1217+
) src 
1218-
	cross apply AssertionXML.nodes('//*[Value = "Disser"]//*[@Role = "has name"]') as T(Appearance)
1218+
on 1 = 0 -- make sure everything is "not matched" below
1219
when not matched then insert ([UID]) values (DEFAULT)
1220-
declare @BellaUID20 varchar(555) = (
1220+
output inserted.[UID] into #Appearance9;
1221-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1221+
1222-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1222+
-- create an equal number of appearances 
1223
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
1224-
declare @assertion20 xml = '
1224+
select app.[UID], t.[UID], r.[RoleUID] 
1225-
	<Assertion PositorUID="' + @BellaUID20 + '" Reliability="0" AssertionTime="2018-12-13 16:00">
1225+
from (select [UID], row_number() over (order by [UID]) as _row from #Appearance9) app
1226-
	  <Posit AppearanceTime="2011-11-11 11:11">
1226+
join (select [UID], row_number() over (order by [UID]) as _row from (
1227-
		<DereferencingSet>
1227+
	select [UID] from #A
1228-
		  <Appearance ThingUID="' + @DisserUID20 + '" Role="husband" />
1228+
	union all
1229-
		  <Appearance ThingUID="' + @BellaUID20 + '" Role="wife" />
1229+
	select [UID] from #B
1230-
		</DereferencingSet>
1230+
	union all
1231-
		<Value>married</Value>
1231+
	select [UID] from #C
1232-
	  </Posit>
1232+
	union all
1233-
	</Assertion>
1233+
	select [UID] from #M
1234-
';
1234+
	union all
1235-
exec Assert @assertion20 OUTPUT;
1235+
	select [UID] from #D
1236
) things ) t 
1237
on t._row = app._row
1238-
declare @BellaUID_Q2 varchar(555) = (
1238+
cross apply (select [RoleUID] from [Role] where [Role] = 'thing') r;
1239-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1239+
1240-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1240+
-- then two more appearances (one for each associated class)
1241
drop table if exists #Appearance10;
1242
create table #Appearance10([UID] uniqueidentifier not null primary key); 
1243-
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@ThingUID = sql:variable("@BellaUID_Q2") and @Role = "wife"]') = 1
1243+
insert into [Thing]([UID]) output inserted.[UID] into #Appearance10 values (DEFAULT);
1244
drop table if exists #Appearance11;
1245
create table #Appearance11([UID] uniqueidentifier not null primary key); 
1246
insert into [Thing]([UID]) output inserted.[UID] into #Appearance11 values (DEFAULT);
1247
1248-
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@ThingUID = sql:variable("@BellaUID_Q2") and @Role = "wife"]') = 1
1248+
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
1249
select app.[UID], c.[UID], r.[RoleUID] 
1250
from [Role] r, #Appearance10 app, #Class1 c 
1251
where r.[Role] = 'class';
1252-
declare @DisserUID21 varchar(555) = (
1252+
insert into [Appearance]([AppearanceUID], [ThingUID], [RoleUID])
1253-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1253+
select app.[UID], c.[UID], r.[RoleUID] 
1254-
	cross apply AssertionXML.nodes('//*[Value = "Disser"]//*[@Role = "has name"]') as T(Appearance)
1254+
from [Role] r, #Appearance11 app, #Class2 c 
1255
where r.[Role] = 'class';
1256-
declare @BellaUID21 varchar(555) = (
1256+
1257-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1257+
-- create dereferencing set things (equal in number to the things we want to classify)
1258-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1258+
drop table if exists #DereferencingSet7;
1259
create table #DereferencingSet7([UID] uniqueidentifier not null primary key); 
1260-
declare @assertion21 xml = '
1260+
merge [Thing] t 
1261-
	<Assertion PositorUID="' + @BellaUID21 + '" Reliability="1.00" AssertionTime="2018-12-13 16:00">
1261+
using #Appearance9 src on 1 = 0 -- make sure everything is "not matched" below
1262-
	  <Posit AppearanceTime="2012-12-12 12:12">
1262+
when not matched then insert ([UID]) values (DEFAULT)
1263-
		<DereferencingSet>
1263+
output inserted.[UID] into #DereferencingSet7;
1264-
		  <Appearance ThingUID="' + @DisserUID21 + '" Role="husband" />
1264+
1265-
		  <Appearance ThingUID="' + @BellaUID21 + '" Role="wife" />
1265+
-- create 22 dereferencing sets
1266-
		</DereferencingSet>
1266+
insert into [DereferencingSet]([DereferencingSetUID]) 
1267-
		<Value>married</Value>
1267+
select [UID]
1268-
	  </Posit>
1268+
from #DereferencingSet7;
1269-
	</Assertion>
1269+
1270-
';
1270+
-- add the appearances to the dereferencing sets
1271-
exec Assert @assertion21 OUTPUT;
1271+
-- first the things
1272
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
1273
select s.[UID], app.[UID]
1274-
declare @BellaUID_Q3 varchar(555) = (
1274+
from (select [UID], row_number() over (order by [UID]) as _row from #DereferencingSet7) s
1275-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1275+
join (select [UID], row_number() over (order by [UID]) as _row from #Appearance9) app
1276-
	cross apply AssertionXML.nodes('//*[Value = "Bella"]//*[@Role = "has name"]') as T(Appearance)
1276+
on s._row = app._row;
1277
-- then the classes
1278
insert into [Dereference]([DereferencingSetUID], [AppearanceUID])
1279-
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@ThingUID = sql:variable("@BellaUID_Q3") and @Role = "wife"]') = 1
1279+
select 
1280
	s.[UID], 
1281
		case 
1282
			when exists (
1283
					select top 1 d.[DereferencingSetUID]
1284
					from [Dereference] d 
1285-
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@ThingUID = sql:variable("@BellaUID_Q3") and @Role = "wife"]') = 1
1285+
					join [Appearance] a
1286
					  on a.[AppearanceUID] = d.[AppearanceUID]
1287-
-- there is currently no way for the system to know that these two relationships (with and without a church) both
1287+
					join (
1288-
-- represent a marriage
1288+
						select [UID] from #A
1289
						union all
1290
						select [UID] from #B
1291
						union all
1292
						select [UID] from #M
1293
						union all
1294
						select [UID] from #D
1295
					) persons
1296
					on persons.[UID] = a.[ThingUID]
1297
					where d.[DereferencingSetUID] = s.[UID]
1298
			) then Person.[UID]
1299
			else Cathedral.[UID]
1300
		end
1301
from #DereferencingSet7 s, #Appearance10 Person, #Appearance11 Cathedral;
1302
1303
-- create posit things
1304
drop table if exists #Posit12;
1305
create table #Posit12([UID] uniqueidentifier not null primary key);
1306-
-- first create three classes: Person, Cathedral, and Church
1306+
merge [Thing] t 
1307-
declare @ModelerUID22 varchar(555) = (
1307+
using #DereferencingSet7 src on 1 = 0 -- make sure everything is "not matched" below
1308-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1308+
when not matched then insert ([UID]) values (DEFAULT)
1309-
	cross apply AssertionXML.nodes('//*[Value = "Modeler"]//*[@Role = "has name"]') as T(Appearance)
1309+
output inserted.[UID] into #Posit12;
1310
1311-
declare @assertion22A xml = '
1311+
-- create posits 
1312-
	<Assertion PositorUID="' + @ModelerUID22 + '" Reliability="1.00" AssertionTime="2018-12-01 00:00">
1312+
insert into [Posit]([PositUID], [DereferencingSetUID], [Value], [AppearanceTime])
1313-
	  <Posit AppearanceTime="1998-12-31 23:59">
1313+
select p.[UID], s.[UID], 'active', '1901-01-01'
1314-
		<DereferencingSet>
1314+
from (select [UID], row_number() over (order by [UID]) as _row from #Posit12) p
1315-
		  <Appearance ThingUID="C" Role="is class" />
1315+
join (select [UID], row_number() over (order by [UID]) as _row from #DereferencingSet7) s
1316-
		</DereferencingSet>
1316+
on p._row = s._row;
1317-
		<Value>Person</Value>
1317+
1318-
	  </Posit>
1318+
-- finally let the Modeler positor assert these
1319-
	</Assertion>
1319+
drop table if exists #Assertion18;
1320-
';
1320+
create table #Assertion18([UID] uniqueidentifier not null primary key);
1321-
exec Assert @assertion22A OUTPUT;
1321+
merge [Thing] t 
1322-
declare @assertion22B xml = '
1322+
using #Posit12 src on 1 = 0 -- make sure everything is "not matched" below
1323-
	<Assertion PositorUID="' + @ModelerUID22 + '" Reliability="1.00" AssertionTime="2018-12-01 00:00">
1323+
when not matched then insert ([UID]) values (DEFAULT)
1324-
	  <Posit AppearanceTime="1998-12-31 23:59">
1324+
output inserted.[UID] into #Assertion18;
1325-
		<DereferencingSet>
1325+
1326-
		  <Appearance ThingUID="C" Role="is class" />
1326+
insert into [Assertion]([AssertionUID], [PositorUID], [PositUID], [Reliability], [AssertionTime])
1327-
		</DereferencingSet>
1327+
select a.[UID], Modeler.[UID], p.[UID], 1, '2018-12-01 00:00'
1328-
		<Value>Cathedral</Value>
1328+
from (select [UID], row_number() over (order by [UID]) as _row from #Assertion18) a
1329-
	  </Posit>
1329+
join (select [UID], row_number() over (order by [UID]) as _row from #Posit12) p
1330-
	</Assertion>
1330+
on a._row = p._row
1331-
';
1331+
cross apply #M Modeler;
1332-
exec Assert @assertion22B OUTPUT;
1332+
1333-
declare @assertion22C xml = '
1333+
1334-
	<Assertion PositorUID="' + @ModelerUID22 + '" Reliability="1.00" AssertionTime="2018-12-01 00:00">
1334+
-- as can be seen there are four things of class Person and one thing of class Cathedral
1335-
	  <Posit AppearanceTime="1998-12-31 23:59">
1335+
1336-
		<DereferencingSet>
1336+
where AssertionXML.exist('/Assertion/Posit/DereferencingSet/Appearance[@Role = "is class" or @Role = "class"]') = 1
1337-
		  <Appearance ThingUID="C" Role="is class" />
1337+
1338-
		</DereferencingSet>
1338+
1339-
		<Value>Church</Value>
1339+
1340-
	  </Posit>
1340+
1341-
	</Assertion>
1341+
1342-
';
1342+
1343-
exec Assert @assertion22C OUTPUT;
1343+
1344
posit p = [{(i1,r1), . . . ,(in,rn)}, v, t], is a structure constructed
1345
by replacing unique identifiers, ij with the unique identifiers of their 
1346
class, Cj, the value, v, with its data type, τ(v), and the time point, t, 
1347
with its data type, τ(t).
1348
-----------------------------------------------------------------------------------------------
1349
1350-
-- now associate some things with the classes
1350+
1351-
declare @ModelerUID23 varchar(555) = (
1351+
values of type varchar(max), so it cannot hold such a structure. It could either
1352-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1352+
be expressed as serialized XML or JSON, or we could let the field contain a 
1353-
	cross apply AssertionXML.nodes('//*[Value = "Modeler"]//*[@Role = "has name"]') as T(Appearance)
1353+
reference to an identifier in a separate table that replicates the structure.
1354
Since a posit type contains a set with variable number of members, it is 
1355-
declare @ArchieUID23 varchar(555) = (
1355+
easier in this case to express it using XML.
1356-
	select Appearance.value('@ThingUID', 'varchar(555)') from v_Assertion 
1356+
*/