schemas and types for json data from theory to practice
play

Schemas And Types For JSON Data: From Theory to Practice - PowerPoint PPT Presentation

Schemas And Types For JSON Data: From Theory to Practice Mohamed-Amine Baazizi 1 Dario Colazzo 2 Giorgio Ghelli 3 Carlo Sartiani 4 2019 ACM SIGMOD/PODS, June 30-July 5, 2019 1 LIP6 - Sorbonne Universit 2 LAMSADE - Universit Paris-Dauphine, PSL


  1. Complexity of validation • Validation is the problem of checking whether a given JSON document J conforms to a given JSON schema S , noted as: • A simple validation algorithm can be devised with complexity bound by • So validation is in PTIME, and proved to be PTIME-hard actually [16]. 20 J ⊨ S O ( | S | ∗ | J | ) , provided that uniqueItems is not used. • Otherwise validation can be performed in O ( | S | ∗ log ( | J | ) ∗ | J | ) time

  2. Expressivity: JSON Schema is inherently as expressive as NFAs • As stated in [16], this construction can be generalised to tree automata • Negative consequence: checking consistency is EXPTIME-hard. • Future research: finding meaningful fragments with better complexity. 21 • JSON string encoding, e.g., ”abbc” → {"a":{"b":{"b":{"c": Null}}}} .

  3. Joi Main features • Joi is a powerful schema language to describe and check at run-time properties of JSON objects exchanged over the Web and that Web applications expect, especially server-side ones. • Large intersection with JSON Schema • But more fluent and readable code 22

  4. Joi Joi = require('joi'); const schema = Joi.string().min(6).max(10); const updatePassword = function (password) { Joi.assert(password, schema); console.log('Validation success!'); }; updatePassword('password'); 23

  5. Joi in action Important: closed record assumption const Joi = require('joi'); const schema = Joi.object().keys({ username: Joi.string().alphanum().min(3).max(30).required(), password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}\$/), access_token: [Joi.string(), Joi.number()], birthyear: Joi.number().integer().min(1900).max(2013), email: Joi.string().email({ minDomainAtoms: 2 }) }).with('username', 'birthyear').without('password', 'access_token'); credit:https://github.com/hapijs/joi 24

  6. Joi in action Important: closed record assumption const Joi = require('joi'); const schema = Joi.object().keys({ username: Joi.string().alphanum().min(3).max(30).required(), password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}\$/), access_token: [Joi.string(), Joi.number()], birthyear: Joi.number().integer().min(1900).max(2013), email: Joi.string().email({ minDomainAtoms: 2 }) }).with('username', 'birthyear').without('password', 'access_token'); Add .unknown() for enabling open record semantics. 25

  7. Back to our NYT schema fragment const Joi = require('joi'); const byline-with-organisation = Joi.object().keys(.......) const byline-wo-organisation = Joi.object().keys(.......) const docSchema = Joi.alternative().try( Joi.any().valid(null), byline-with-organisation, byline-wo-organisation ) 26

  8. JSON Schema vs Joi more verbose, expressed in JSON much more expressive expressing properties of base values limited expressive power for done to fix boundaries) limited support (work needs to be negation full support for union, disjunction, more fluent to write/read exist) JSON Schema bound to JavaScript (but translators language independent but poor documentation many use cases available on the web, better documented closed record types open record types Joi 27

  9. Conclusive remarks on schemas • We focused on JSON Schema and Joi. • Other proposals exists, like JSound and Mongoose, but with much less impact • Work still needed in the standardisation, documentation, and specification of formal semantics 28

  10. Schema Tools

  11. Schema Tools Our contribution

  12. Schema Inference for Semistructured JSON Data • Schemas for the analyst and for the system • Structured and semistructured data • Fully formalized • Simple • Simple parallelizable algorithms • Parametric • Extensible 29

  13. Schema Inference for Semistructured JSON Data • Schemas for the analyst and for the system • Structured and semistructured data • Fully formalized • Simple • Simple parallelizable algorithms • Parametric • Extensible 29

  14. Schema Inference for Semistructured JSON Data • Schemas for the analyst and for the system • Structured and semistructured data • Fully formalized • Simple • Simple parallelizable algorithms • Parametric • Extensible 29

  15. Schema Inference for Semistructured JSON Data • Schemas for the analyst and for the system • Structured and semistructured data • Fully formalized • Simple • Simple parallelizable algorithms • Parametric • Extensible 29

  16. Schema Inference for Semistructured JSON Data • Schemas for the analyst and for the system • Structured and semistructured data • Fully formalized • Simple • Simple parallelizable algorithms • Parametric • Extensible 29

  17. Schema Inference for Semistructured JSON Data • Schemas for the analyst and for the system • Structured and semistructured data • Fully formalized • Simple • Simple parallelizable algorithms • Parametric • Extensible 29

  18. Schema Inference for Semistructured JSON Data • Schemas for the analyst and for the system • Structured and semistructured data • Fully formalized • Simple • Simple parallelizable algorithms • Parametric • Extensible 29

  19. Schema Inference for Semistructured JSON Data • Schemas for the analyst and for the system • Structured and semistructured data • Fully formalized • Simple • Simple parallelizable algorithms • Parametric • Extensible 29

  20. The type system Arrays JSON expressions Records 30 Basic values B ::= null | true | false | n | s n ∈ Number , s ∈ String R ::= { l 1 : J 1 , . . . , l n : J n } n ≥ 0 A ::= [ J 1 , . . . , J n ] n ≥ 0 J ::= B | R | A

  21. The type system Basic types Records Arrays JSON expressions 30 B ::= Null | Bool | Num | Str R ::= { l 1 : J 1 , . . . , l n : J n } n ≥ 0 A ::= [ J 1 , . . . , J n ] n ≥ 0 J ::= B | R | A

  22. The type system Basic types Record types Arrays JSON expressions 30 B ::= Null | Bool | Num | Str q i ∈ { ′ ! ′ , ′ ? ′ } n ≥ 0 R ::= { l 1 : T 1 q 1 , . . . , l n : T n q n } A ::= [ J 1 , . . . , J n ] n ≥ 0 J ::= B | R | A

  23. The type system Basic types Record types Array types JSON expressions 30 B ::= Null | Bool | Num | Str q i ∈ { ′ ! ′ , ′ ? ′ } n ≥ 0 R ::= { l 1 : T 1 q 1 , . . . , l n : T n q n } A ::= [ T ] J ::= B | R | A

  24. The type system Basic types Record types Array types JSON types 30 B ::= Null | Bool | Num | Str q i ∈ { ′ ! ′ , ′ ? ′ } n ≥ 0 R ::= { l 1 : T 1 q 1 , . . . , l n : T n q n } A ::= [ T ] T ::= B | R | A | +( T 1 , . . . , T n ) n ≥ 0

  25. • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, … • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: • No choice is “better”, it is even possible that I want to see more/less information in different moments 31

  26. • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, … • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: • No choice is “better”, it is even possible that I want to see more/less information in different moments 31

  27. • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Type flexibility • Assume a collection: • We can represent it as: • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • Or more precisely as: • Or even: • No choice is “better”, it is even possible that I want to see more/less information in different moments 31 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …

  28. • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: • No choice is “better”, it is even possible that I want to see more/less information in different moments 31 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …

  29. • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: • No choice is “better”, it is even possible that I want to see more/less information in different moments 31 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, … • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}*

  30. • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: • No choice is “better”, it is even possible that I want to see more/less information in different moments 31 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, … • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}*

  31. • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: • No choice is “better”, it is even possible that I want to see more/less information in different moments 31 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, … • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}*

  32. • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: • No choice is “better”, it is even possible that I want to see more/less information in different moments 31 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, … • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}*

  33. Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: + { a: Int, b: Int, e: Int, f: Int}* • No choice is “better”, it is even possible that I want to see more/less information in different moments 31 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, … • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}*

  34. Type flexibility • Assume a collection: • We can represent it as: • Or more precisely as: • Or even: + { a: Int, b: Int, e: Int, f: Int}* • No choice is “better”, it is even possible that I want to see more/less information in different moments 31 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, … • { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • { a: Int, b: Int, c: Int, d: Int}* + { a: Int, b: Str, c: Str, d: Int}*

  35. The equivalence parameter approach • The parameter: we let the analyst to decide size vs precision by fixing a parameter • The equivalence parameter: the analyst choses a notion of similarity – two types are merged into one if they are “similar enough” 32

  36. The equivalence parameter approach • The parameter: we let the analyst to decide size vs precision by fixing a parameter • The equivalence parameter: the analyst choses a notion of similarity – two types are merged into one if they are “similar enough” 32

  37. The equivalence parameter approach • The parameter: we let the analyst to decide size vs precision by fixing a parameter • The equivalence parameter: the analyst choses a notion of similarity – two types are merged into one if they are “similar enough” 32

  38. • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Useful equivalences • K-equivalence: all records are similar: • L-equivalence: two records are equivalent if they have the same labels: • Others 33

  39. • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Useful equivalences • K-equivalence: all records are similar: • L-equivalence: two records are equivalent if they have the same labels: • Others 33

  40. { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Useful equivalences • K-equivalence: all records are similar: • L-equivalence: two records are equivalent if they have the same labels: • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , • Others 33 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}*

  41. • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* Useful equivalences • K-equivalence: all records are similar: • L-equivalence: two records are equivalent if they have the same labels: • Others 33 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}*

  42. Useful equivalences • K-equivalence: all records are similar: • L-equivalence: two records are equivalent if they have the same labels: { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • Others 33 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …:

  43. Useful equivalences • K-equivalence: all records are similar: • L-equivalence: two records are equivalent if they have the same labels: { a: Int, b: (Int+Str), c: (Int+Str), d: Int}* + { a: Int, b: Int, e: Int, f: Int}* • Others 33 • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …: { a: Int, b: (Int+Str), c: (Int+Str)?, d: Int?, e: Int?, f: Int?}* • { a: 0, b: 1, c: 2, d: 0} , { a: 3, b: 1, e: 3, f: 2} , { a: 3, b: ‘a’, c: ‘b’, d: 3} , { a: , b: , e: , f: }, …:

  44. Our system • We formalized that through a set of type rules • We experimented a Spark map-reduce implementation 34

  45. Our system • We formalized that through a set of type rules • We experimented a Spark map-reduce implementation 34

  46. Our system • We formalized that through a set of type rules • We experimented a Spark map-reduce implementation 34

  47. The equivalence approach • Simple • Highly parallelizable • Parametric • But: too inflexible, in practice you would not employ the same equivalence everywhere 35

  48. The equivalence approach • Simple • Highly parallelizable • Parametric • But: too inflexible, in practice you would not employ the same equivalence everywhere 35

  49. The equivalence approach • Simple • Highly parallelizable • Parametric • But: too inflexible, in practice you would not employ the same equivalence everywhere 35

  50. The equivalence approach • Simple • Highly parallelizable • Parametric • But: too inflexible, in practice you would not employ the same equivalence everywhere 35

  51. The equivalence approach • Simple • Highly parallelizable • Parametric • But: too inflexible, in practice you would not employ the same equivalence everywhere 35

  52. }) Interactive workbench }) }) 36 + K ({ docs : + K ({ byline : + K ({ organization : + K (Str)? original : + K (Str) person :[ + K ({fn : + K (Str)?, ln : + K (Str)?, mn : + K (Str)?, org : + K (Str)?}) ]

  53. The byline }) }) 37 + K ({ byline : + K ({ organization : + K (Str)? original : + K (Str) person :[ + K ({ fn : + K (Str)?, ln : + K (Str)?, mn : + K (Str)?, org : + K (Str)?}) ]

  54. Expanding the byline ) }) 38 + K ({ byline : + L ({ organization : + K (Str) original : + K (Str) person :[ + K () ] }, {original : + K (Str) person :[ + K ({ fn : + K (Str)?, ln : + K (Str)?, mn : + K (Str)?, org : + K (Str)?}) ] }

  55. Collapsing the byline }) }) 39 + K ({ byline : + K ({ organization : + K (Str)? original : + K (Str) person :[ + K ({ fn : + K (Str)?, ln : + K (Str)?, mn : + K (Str)?, org : + K (Str)?}) ]

  56. }) Expanding person }) 40 + K ({ byline : + K ({ organization : + K (Str)? original : + K (Str) person : [ + L ({ fn : + K (Str), ln : + K (Str), mn : + K (Str)}, { org : + K (Str)} ) ]

  57. Expanding person - two { ln : …, org :…}, }) }) { ln : …} ) ] { fn : …, mn :…}, { fn : …, mn :…, org :…}, { fn : …}, { fn : …, org :…}, { fn : …, ln : …}, { fn : …, ln : …, org :…}, { fn : …, ln : …, mn :…}, 41 + K ({ byline : + K ({ organization : + K (Str)? original : + K (Str) person : [ + L ({ fn : …, ln : …, mn :…, org :…},

  58. Counting • We infer this type { title : Str ; text : [ Str ] + Null ; author : { address : T? ; affiliation : T? ; …}? ; abstract : Str? } • How common is ‘optional’? How frequent is a branch? How big a collection? 42

  59. Counting • We infer this type { title : Str ; text : [ Str ] + Null ; author : { address : T? ; affiliation : T? ; …}? ; abstract : Str? } • How common is ‘optional’? How frequent is a branch? How big a collection? 42

  60. Counting • We infer this type { title : Str ; text : [ Str ] + Null ; author : { address : T? ; affiliation : T? ; …}? ; abstract : Str? } • How common is ‘optional’? How frequent is a branch? How big a collection? 42

  61. Let us count { title : Str, text : ([ Str ] + Null), author : { address : T?, affiliation : T?, …}?, abstract : Str? } 1000 43

  62. Let us count { title : Str, text : ([ Str ] + Null), author : { address : T?, affiliation : T?, …}?, abstract : Str? } 1000 43

  63. Let us count { title : Str 1000 , text : ([ Str ] + Null), author : { address : T?, affiliation : T?, …}?, abstract : Str? } 1000 43

  64. Let us count { title : Str 1000 , text : ([ Str ] + Null) 1000 , author : { address : T?, affiliation : T?, …}?, abstract : Str? } 1000 43

  65. Let us count { title : Str 1000 , author : { address : T?, affiliation : T?, …}?, abstract : Str? } 1000 43 text : ([ Str ] 800 + Null) 1000 ,

  66. Let us count { title : Str 1000 , author : { address : T?, affiliation : T?, …}?, abstract : Str? } 1000 43 text : ([ Str ] 800 + Null 200 ) 1000 ,

  67. Let us count { title : Str 1000 , author : { address : T?, affiliation : T?, …}?, abstract : Str? } 1000 43 text : ([ Str 8000 ] 800 + Null 200 ) 1000 ,

  68. Let us count { title : Str 1000 , author : { address : T?, affiliation : T?, …} 800 , abstract : Str 20 } 1000 43 text : ([ Str 8000 ] 800 + Null 200 ) 1000 ,

  69. Let us count { title : Str 1000 , author : { address : T 400 , affiliation : T?, …} 800 , abstract : Str 20 } 1000 43 text : ([ Str 8000 ] 800 + Null 200 ) 1000 ,

  70. Let us count { title : Str 1000 , author : { address : T 400 , affiliation : T 200 , …} 800 , abstract : Str 20 } 1000 43 text : ([ Str 8000 ] 800 + Null 200 ) 1000 ,

  71. Let us count { title : Str 1000 , author : ({ address : T 400 , …} 400 + { affiliation : T 200 , …} 400 ) 800 , abstract : Str 20 } 1000 43 text : ([ Str 8000 ] 800 + Null 200 ) 1000 ,

  72. Conclusions • A family of approaches • Simple, fully formalized • Parametric • Parallelizable 44

  73. Conclusions • A family of approaches • Simple, fully formalized • Parametric • Parallelizable 44

  74. Conclusions • A family of approaches • Simple, fully formalized • Parametric • Parallelizable 44

  75. Conclusions • A family of approaches • Simple, fully formalized • Parametric • Parallelizable 44

  76. Conclusions • A family of approaches • Simple, fully formalized • Parametric • Parallelizable 44

Recommend


More recommend