diff --git a/Server version/Blackbox/Duniter/Mod/Blockchain.odc b/Server version/Blackbox/Duniter/Mod/Blockchain.odc index 6d151ca..a75d5be 100644 Binary files a/Server version/Blackbox/Duniter/Mod/Blockchain.odc and b/Server version/Blackbox/Duniter/Mod/Blockchain.odc differ diff --git a/Server version/Blackbox/Duniter/Mod/Server.odc b/Server version/Blackbox/Duniter/Mod/Server.odc index 2242ae2..26f5155 100644 Binary files a/Server version/Blackbox/Duniter/Mod/Server.odc and b/Server version/Blackbox/Duniter/Mod/Server.odc differ diff --git a/Server version/Blackbox/Duniter/Mod/WWViews.odc b/Server version/Blackbox/Duniter/Mod/WWViews.odc index 7436806..77bfde5 100644 Binary files a/Server version/Blackbox/Duniter/Mod/WWViews.odc and b/Server version/Blackbox/Duniter/Mod/WWViews.odc differ diff --git a/Server version/Blackbox/Util/Bab/Json.odc b/Server version/Blackbox/Util/Bab/Json.odc index 8d6db85..b5a2240 100644 Binary files a/Server version/Blackbox/Util/Bab/Json.odc and b/Server version/Blackbox/Util/Bab/Json.odc differ diff --git a/Server version/Blackbox/Util/Mod/Alea.odc b/Server version/Blackbox/Util/Mod/Alea.odc index 68bb856..6aa77b4 100644 Binary files a/Server version/Blackbox/Util/Mod/Alea.odc and b/Server version/Blackbox/Util/Mod/Alea.odc differ diff --git a/Server version/Blackbox/Util/Mod/Sets.odc b/Server version/Blackbox/Util/Mod/Sets.odc index 34eb438..bdce879 100644 Binary files a/Server version/Blackbox/Util/Mod/Sets.odc and b/Server version/Blackbox/Util/Mod/Sets.odc differ diff --git a/Server version/Sources/Duniter/Blockchain.txt b/Server version/Sources/Duniter/Blockchain.txt index a89f65b..fcf6b6c 100644 --- a/Server version/Sources/Duniter/Blockchain.txt +++ b/Server version/Sources/Duniter/Blockchain.txt @@ -1559,7 +1559,7 @@ MODULE DuniterBlockchain; VAR - i, idRef, jlRef, n, res: INTEGER; + i, idRef, jlRef, n, res, bnb: INTEGER; tt: LONGINT; s: ARRAY 101 OF CHAR; b: BOOLEAN; @@ -1604,6 +1604,7 @@ MODULE DuniterBlockchain; END; ASSERT(id.hash # "", 104); Strings.StringToInt(nb, id.block_number, res); ASSERT(res = 0, 105); + bnb := id.block_number; NEW(idU); NEW(idU.c, LEN(id.uid$) + 1); idU.c^ := id.uid$; NEW(idP); idP.ref := id.pubkey; IF idPubT.SearchIns(idP) THEN @@ -1642,7 +1643,7 @@ MODULE DuniterBlockchain; END; NEW(jlL); jlL.next := jl .list; - jlL.joiningBlock := id.block_number; + jlL.joiningBlock := bnb; jlL.leavingBlock := hasNotLeaved; jl.list := joinAndLeaveLMan.WriteAllocateData(jlL); joinAndLeaveMan.WriteData(jlRef, jl); @@ -1653,7 +1654,7 @@ MODULE DuniterBlockchain; END; i := 1; - WHILE ssA[i] # ']' DO (* actives : Update *) + WHILE ssA[i] # ']' DO (* actives *) INC(i); NEW(idP); ScanS(ssA, ':', idP.ref, i); diff --git a/Server version/Sources/Duniter/Server.txt b/Server version/Sources/Duniter/Server.txt index 32dcf02..3c4300d 100644 --- a/Server version/Sources/Duniter/Server.txt +++ b/Server version/Sources/Duniter/Server.txt @@ -22,10 +22,10 @@ MODULE DuniterServer; CONST - version = "2.3.3se"; + version = "2.4.0se"; rsrcDir = "Duniter/Rsrc"; (* Directory for the two following files *) - parametersName = "Parameters.txt"; (* File containing the greatest allowed allocated memory size and the longest run time for W.CalcPermutations *) + parametersName = "Parameters.txt"; (* File containing the greatest allowed allocated memory size for W.CalcPermutations *) runningName = "Running.odc"; (* File whose existence shows that WWServer.exe is running *) textMeta = "WWMeta.json"; (* Json file containing metadata *) diff --git a/Server version/Sources/Duniter/WWViews.txt b/Server version/Sources/Duniter/WWViews.txt index 1dbd2e0..d59496a 100644 --- a/Server version/Sources/Duniter/WWViews.txt +++ b/Server version/Sources/Duniter/WWViews.txt @@ -603,40 +603,42 @@ MODULE DuniterWWViews; ASSERT(f1[1].value IS J.JsonVal, 103); ASSERT(f1[1].value(J.JsonVal).json IS J.Array, 104); d := f1[1].value(J.JsonVal).json(J.Array).elements; - FOR i := 0 TO LEN(d) - 1 DO - ASSERT(d[i] IS J.JsonVal, 105); - ASSERT(d[i](J.JsonVal).json IS J.Object, 106); - f2 := d[i](J.JsonVal).json(J.Object).fields; - ASSERT(f2[0].name$ = "after", 107); - ASSERT(f2[0].value IS J.Bool, 108); - ASSERT(f2[1].name$ = "date", 109); - ASSERT(f2[1].value IS J.String, 110); - ASSERT(f2[2].name$ = "names", 111); - ASSERT(f2[2].value IS J.JsonVal, 112); - ASSERT(f2[2].value(J.JsonVal).json IS J.Array, 113); - n := f2[2].value(J.JsonVal).json(J.Array).elements; - FOR k := 0 TO LEN(n) - 1 DO - ASSERT(n[k] IS J.JsonVal, 114); - ASSERT(n[k](J.JsonVal).json IS J.Object, 115); - f3 := n[k](J.JsonVal).json(J.Object).fields; - ASSERT(f3[0].name$ = "name", 116); - ASSERT(f3[0].value IS J.String, 117); - ASSERT(f3[1].name$ = "proba", 118); - ASSERT(f3[1].value IS J.Integer, 119); - NEW(pD); - pD.after := f2[0].value(J.Bool).bool; - pD.date := BA.StringToTimestamp(f2[1].value(J.String).s$); - pD.id := f3[0].value(J.String).s; - pD.proba := SHORT(f3[1].value(J.Integer).n); - e := pD; - b := oD.SearchIns(e, m); ASSERT(~b, 120); - NEW(pM); - pM.after := pD.after; - pM.date := pD.date; - pM.id := pD.id; - pM.proba := pD.proba; - e := pM; - b := oN.SearchIns(e, m); ASSERT(~b, 121); + IF d # NIL THEN + FOR i := 0 TO LEN(d) - 1 DO + ASSERT(d[i] IS J.JsonVal, 105); + ASSERT(d[i](J.JsonVal).json IS J.Object, 106); + f2 := d[i](J.JsonVal).json(J.Object).fields; + ASSERT(f2[0].name$ = "after", 107); + ASSERT(f2[0].value IS J.Bool, 108); + ASSERT(f2[1].name$ = "date", 109); + ASSERT(f2[1].value IS J.String, 110); + ASSERT(f2[2].name$ = "names", 111); + ASSERT(f2[2].value IS J.JsonVal, 112); + ASSERT(f2[2].value(J.JsonVal).json IS J.Array, 113); + n := f2[2].value(J.JsonVal).json(J.Array).elements; + FOR k := 0 TO LEN(n) - 1 DO + ASSERT(n[k] IS J.JsonVal, 114); + ASSERT(n[k](J.JsonVal).json IS J.Object, 115); + f3 := n[k](J.JsonVal).json(J.Object).fields; + ASSERT(f3[0].name$ = "name", 116); + ASSERT(f3[0].value IS J.String, 117); + ASSERT(f3[1].name$ = "proba", 118); + ASSERT(f3[1].value IS J.Integer, 119); + NEW(pD); + pD.after := f2[0].value(J.Bool).bool; + pD.date := BA.StringToTimestamp(f2[1].value(J.String).s$); + pD.id := f3[0].value(J.String).s; + pD.proba := SHORT(f3[1].value(J.Integer).n); + e := pD; + b := oD.SearchIns(e, m); ASSERT(~b, 120); + NEW(pM); + pM.after := pD.after; + pM.date := pD.date; + pM.id := pD.id; + pM.proba := pD.proba; + e := pM; + b := oN.SearchIns(e, m); ASSERT(~b, 121); + END; END; END; END; diff --git a/Server version/Sources/Util/Alea.txt b/Server version/Sources/Util/Alea.txt index f737984..324d7a9 100644 --- a/Server version/Sources/Util/Alea.txt +++ b/Server version/Sources/Util/Alea.txt @@ -81,7 +81,7 @@ MODULE UtilAlea; v2 := 2. * g.Random() - 1.; r := v1 * v1 + v2 * v2; UNTIL (r < 1.) & (r > 0.); - r := Math.Sqrt( - 2. * Math.Ln(r) / r); + r := Math.Sqrt( -2. * Math.Ln(r) / r); g.g := v1 * r; RETURN v2 * r; END; diff --git a/Server version/Sources/Util/Bab/Json.txt b/Server version/Sources/Util/Bab/Json.txt index 749db4b..b8d8f79 100644 --- a/Server version/Sources/Util/Bab/Json.txt +++ b/Server version/Sources/Util/Bab/Json.txt @@ -1,3 +1,15 @@ +{ +Util: Utility tools. + +Copyright (C) 2017…2018 GérardMeunier + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} + BABEL UtilJson; diff --git a/Server version/Sources/Util/Sets.txt b/Server version/Sources/Util/Sets.txt index 230b71a..ca8c069 100644 --- a/Server version/Sources/Util/Sets.txt +++ b/Server version/Sources/Util/Sets.txt @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with thi MODULE UtilSets; - (**) + (* The module UtilSets implements the type Set, a set of non-negative integers, represented by intervals. *) diff --git a/Standalone version/Blackbox/Duniter0/Docu/Identities.odc b/Standalone version/Blackbox/Duniter0/Docu/Identities.odc index f66ecbf..afb5957 100644 Binary files a/Standalone version/Blackbox/Duniter0/Docu/Identities.odc and b/Standalone version/Blackbox/Duniter0/Docu/Identities.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Docu/MakingOf.odc b/Standalone version/Blackbox/Duniter0/Docu/MakingOf.odc index 8ec9ba0..7d736b9 100644 Binary files a/Standalone version/Blackbox/Duniter0/Docu/MakingOf.odc and b/Standalone version/Blackbox/Duniter0/Docu/MakingOf.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Docu/Manual.odc b/Standalone version/Blackbox/Duniter0/Docu/Manual.odc index 538d3f8..abd27e1 100644 Binary files a/Standalone version/Blackbox/Duniter0/Docu/Manual.odc and b/Standalone version/Blackbox/Duniter0/Docu/Manual.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Docu/fr/Identities.odc b/Standalone version/Blackbox/Duniter0/Docu/fr/Identities.odc index 188868d..084e429 100644 Binary files a/Standalone version/Blackbox/Duniter0/Docu/fr/Identities.odc and b/Standalone version/Blackbox/Duniter0/Docu/fr/Identities.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Docu/fr/Manual.odc b/Standalone version/Blackbox/Duniter0/Docu/fr/Manual.odc index b530bef..8c9e32d 100644 Binary files a/Standalone version/Blackbox/Duniter0/Docu/fr/Manual.odc and b/Standalone version/Blackbox/Duniter0/Docu/fr/Manual.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/Basic.odc b/Standalone version/Blackbox/Duniter0/Mod/Basic.odc index 5429d6b..0267327 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/Basic.odc and b/Standalone version/Blackbox/Duniter0/Mod/Basic.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/Blockchain.odc b/Standalone version/Blackbox/Duniter0/Mod/Blockchain.odc index 5c14f10..d23dba2 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/Blockchain.odc and b/Standalone version/Blackbox/Duniter0/Mod/Blockchain.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/Centralities.odc b/Standalone version/Blackbox/Duniter0/Mod/Centralities.odc new file mode 100644 index 0000000..203df56 Binary files /dev/null and b/Standalone version/Blackbox/Duniter0/Mod/Centralities.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/CentralitiesJson.odc b/Standalone version/Blackbox/Duniter0/Mod/CentralitiesJson.odc new file mode 100644 index 0000000..abfad32 Binary files /dev/null and b/Standalone version/Blackbox/Duniter0/Mod/CentralitiesJson.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/Clock.odc b/Standalone version/Blackbox/Duniter0/Mod/Clock.odc index 9e95cf9..c4d5839 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/Clock.odc and b/Standalone version/Blackbox/Duniter0/Mod/Clock.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/IdentitySearch.odc b/Standalone version/Blackbox/Duniter0/Mod/IdentitySearch.odc index 2349ef1..0813d19 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/IdentitySearch.odc and b/Standalone version/Blackbox/Duniter0/Mod/IdentitySearch.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/Members.odc b/Standalone version/Blackbox/Duniter0/Mod/Members.odc index 859e507..74a8ba8 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/Members.odc and b/Standalone version/Blackbox/Duniter0/Mod/Members.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/MembersPrint.odc b/Standalone version/Blackbox/Duniter0/Mod/MembersPrint.odc index c59111a..bd29b14 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/MembersPrint.odc and b/Standalone version/Blackbox/Duniter0/Mod/MembersPrint.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/QualitiesJson.odc b/Standalone version/Blackbox/Duniter0/Mod/QualitiesJson.odc new file mode 100644 index 0000000..af9aedf Binary files /dev/null and b/Standalone version/Blackbox/Duniter0/Mod/QualitiesJson.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/QualitiesSetsArr.odc b/Standalone version/Blackbox/Duniter0/Mod/QualitiesSetsArr.odc new file mode 100644 index 0000000..45099ce Binary files /dev/null and b/Standalone version/Blackbox/Duniter0/Mod/QualitiesSetsArr.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/Sandbox.odc b/Standalone version/Blackbox/Duniter0/Mod/Sandbox.odc index 74b4919..33c6ecd 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/Sandbox.odc and b/Standalone version/Blackbox/Duniter0/Mod/Sandbox.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/WWViews.odc b/Standalone version/Blackbox/Duniter0/Mod/WWViews.odc index 0f91643..351dd90 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/WWViews.odc and b/Standalone version/Blackbox/Duniter0/Mod/WWViews.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/WotWizard.odc b/Standalone version/Blackbox/Duniter0/Mod/WotWizard.odc index 1833b52..358ef66 100644 Binary files a/Standalone version/Blackbox/Duniter0/Mod/WotWizard.odc and b/Standalone version/Blackbox/Duniter0/Mod/WotWizard.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Mod/WotWizardPrint.odc b/Standalone version/Blackbox/Duniter0/Mod/WotWizardPrint.odc deleted file mode 100644 index dbad856..0000000 Binary files a/Standalone version/Blackbox/Duniter0/Mod/WotWizardPrint.odc and /dev/null differ diff --git a/Standalone version/Blackbox/Duniter0/Rsrc/Clock.odc b/Standalone version/Blackbox/Duniter0/Rsrc/Clock.odc index a72137d..408b9af 100644 Binary files a/Standalone version/Blackbox/Duniter0/Rsrc/Clock.odc and b/Standalone version/Blackbox/Duniter0/Rsrc/Clock.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Rsrc/Documentation.odc b/Standalone version/Blackbox/Duniter0/Rsrc/Documentation.odc index 7abc6ae..7c57d7a 100644 Binary files a/Standalone version/Blackbox/Duniter0/Rsrc/Documentation.odc and b/Standalone version/Blackbox/Duniter0/Rsrc/Documentation.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Rsrc/Identities.odc b/Standalone version/Blackbox/Duniter0/Rsrc/Identities.odc index d7e11c0..759ca9e 100644 Binary files a/Standalone version/Blackbox/Duniter0/Rsrc/Identities.odc and b/Standalone version/Blackbox/Duniter0/Rsrc/Identities.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Rsrc/SA-Menus.odc b/Standalone version/Blackbox/Duniter0/Rsrc/SA-Menus.odc index f7a9451..351e11f 100644 Binary files a/Standalone version/Blackbox/Duniter0/Rsrc/SA-Menus.odc and b/Standalone version/Blackbox/Duniter0/Rsrc/SA-Menus.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Rsrc/Sources.odc b/Standalone version/Blackbox/Duniter0/Rsrc/Sources.odc index c457e89..534f152 100644 Binary files a/Standalone version/Blackbox/Duniter0/Rsrc/Sources.odc and b/Standalone version/Blackbox/Duniter0/Rsrc/Sources.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Rsrc/Strings.odc b/Standalone version/Blackbox/Duniter0/Rsrc/Strings.odc index 1ac87e6..64c40f5 100644 Binary files a/Standalone version/Blackbox/Duniter0/Rsrc/Strings.odc and b/Standalone version/Blackbox/Duniter0/Rsrc/Strings.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Rsrc/Version.odc b/Standalone version/Blackbox/Duniter0/Rsrc/Version.odc new file mode 100644 index 0000000..76d9220 Binary files /dev/null and b/Standalone version/Blackbox/Duniter0/Rsrc/Version.odc differ diff --git a/Standalone version/Blackbox/Duniter0/Rsrc/fr/Strings.odc b/Standalone version/Blackbox/Duniter0/Rsrc/fr/Strings.odc index 32f2b15..2dcf095 100644 Binary files a/Standalone version/Blackbox/Duniter0/Rsrc/fr/Strings.odc and b/Standalone version/Blackbox/Duniter0/Rsrc/fr/Strings.odc differ diff --git a/Standalone version/Blackbox/Util/Bab/Json.odc b/Standalone version/Blackbox/Util/Bab/Json.odc index 8d6db85..b5a2240 100644 Binary files a/Standalone version/Blackbox/Util/Bab/Json.odc and b/Standalone version/Blackbox/Util/Bab/Json.odc differ diff --git a/Standalone version/Blackbox/Util/Docu/Sets.odc b/Standalone version/Blackbox/Util/Docu/Sets.odc index 6bc8de0..62ad37e 100644 Binary files a/Standalone version/Blackbox/Util/Docu/Sets.odc and b/Standalone version/Blackbox/Util/Docu/Sets.odc differ diff --git a/Standalone version/Blackbox/Util/Mod/Alea.odc b/Standalone version/Blackbox/Util/Mod/Alea.odc index 68bb856..6aa77b4 100644 Binary files a/Standalone version/Blackbox/Util/Mod/Alea.odc and b/Standalone version/Blackbox/Util/Mod/Alea.odc differ diff --git a/Standalone version/Blackbox/Util/Mod/Net.odc b/Standalone version/Blackbox/Util/Mod/Net.odc new file mode 100644 index 0000000..e96bca6 Binary files /dev/null and b/Standalone version/Blackbox/Util/Mod/Net.odc differ diff --git a/Standalone version/Blackbox/Util/Mod/Sets.odc b/Standalone version/Blackbox/Util/Mod/Sets.odc index e40c60d..bdce879 100644 Binary files a/Standalone version/Blackbox/Util/Mod/Sets.odc and b/Standalone version/Blackbox/Util/Mod/Sets.odc differ diff --git a/Standalone version/Documentation/MakingOf.txt b/Standalone version/Documentation/MakingOf.txt index 2c801aa..712c065 100644 --- a/Standalone version/Documentation/MakingOf.txt +++ b/Standalone version/Documentation/MakingOf.txt @@ -21,8 +21,10 @@ Kernel$+ Files HostFiles HostPackedFiles StdLoader 1 Move.cur 2 Copy.cur 3 Link.cur 4 Pick.cur 5 Stop.cur 6 Hand.cur 7 Table.cur DevPacker.PackThis WotWizard.exe := -Babel/Code/Compil.ocf Dev/Code/Search.ocf Duniter0/Code/Basic.ocf Duniter0/Code/Blockchain.ocf Duniter0/Code/CertificationsPrint.ocf Duniter0/Code/Certifiers.ocf Duniter0/Code/Clock.ocf Duniter0/Code/Dates.ocf Duniter0/Code/IdentitiesPrint.ocf Duniter0/Code/IdentitySearch.ocf Duniter0/Code/Members.ocf Duniter0/Code/MembersPrint.ocf Duniter0/Code/ParametersPrint.ocf Duniter0/Code/Sandbox.ocf Duniter0/Code/SandboxPrint.ocf Duniter0/Code/SentriesPrint.ocf Duniter0/Code/WWViews.ocf Duniter0/Code/WotWizard.ocf Duniter0/Code/WotWizardPrint.ocf Host/Code/CFrames.ocf Host/Code/Clipboard.ocf Host/Code/Cmds.ocf Host/Code/Dialog.ocf Host/Code/Files.ocf Host/Code/Fonts.ocf Host/Code/Mechanisms.ocf Host/Code/Menus.ocf Host/Code/Ports.ocf Host/Code/Printers.ocf Host/Code/Registry.ocf Host/Code/Windows.ocf Ole/Code/Data.ocf Sql/Code/DB.ocf Sql/Code/Drivers.ocf Std/Code/Api.ocf Std/Code/CFrames.ocf Std/Code/Cmds.ocf Std/Code/Dialog.ocf Std/Code/Interpreter.ocf Std/Code/Links.ocf Std/Code/Loader.ocf Std/Code/Log.ocf Std/Code/MenuTool.ocf System/Code/Containers.ocf System/Code/Controllers.ocf System/Code/Controls.ocf System/Code/Converters.ocf System/Code/Dates.ocf System/Code/Dialog.ocf System/Code/Documents.ocf System/Code/Files.ocf System/Code/Fonts.ocf System/Code/Init.ocf System/Code/Kernel.ocf System/Code/Log.ocf System/Code/Math.ocf System/Code/Mechanisms.ocf System/Code/Meta.ocf System/Code/Models.ocf System/Code/Ports.ocf System/Code/Printers.ocf System/Code/Printing.ocf System/Code/Properties.ocf System/Code/Sequencers.ocf System/Code/Services.ocf System/Code/Stores.ocf System/Code/Strings.ocf System/Code/Views.ocf System/Code/Windows.ocf Text/Code/Cmds.ocf Text/Code/Controllers.ocf Text/Code/Mappers.ocf Text/Code/Models.ocf Text/Code/Rulers.ocf Text/Code/Setters.ocf Text/Code/Views.ocf Unicode/Code/Case_Mapping.ocf Unicode/Code/Letter_Mapping.ocf Util/Code/Alea.ocf Util/Code/AvlTree.ocf Util/Code/BBTree.ocf Util/Code/BTree.ocf Util/Code/Json.ocf Util/Code/Sets.ocf Util/Code/Sort.ocf +Babel/Code/Compil.ocf Duniter0/Code/Basic.ocf Duniter0/Code/Blockchain.ocf Duniter0/Code/Centralities.ocf Duniter0/Code/CentralitiesJson.ocf Duniter0/Code/CertificationsPrint.ocf Duniter0/Code/Certifiers.ocf Duniter0/Code/Clock.ocf Duniter0/Code/Dates.ocf Duniter0/Code/IdentitiesPrint.ocf Duniter0/Code/IdentitySearch.ocf Duniter0/Code/Members.ocf Duniter0/Code/MembersPrint.ocf Duniter0/Code/ParametersPrint.ocf Duniter0/Code/QualitiesJson.ocf Duniter0/Code/QualitiesSetsArr.ocf Duniter0/Code/Sandbox.ocf Duniter0/Code/SandboxPrint.ocf Duniter0/Code/SentriesPrint.ocf Duniter0/Code/WWViews.ocf Duniter0/Code/WotWizard.ocf Host/Code/CFrames.ocf Host/Code/Clipboard.ocf Host/Code/Cmds.ocf Host/Code/Dialog.ocf Host/Code/Files.ocf Host/Code/Fonts.ocf Host/Code/Mechanisms.ocf Host/Code/Menus.ocf Host/Code/Ports.ocf Host/Code/Printers.ocf Host/Code/Registry.ocf Host/Code/Windows.ocf Ole/Code/Data.ocf Sql/Code/DB.ocf Sql/Code/Drivers.ocf Std/Code/Api.ocf Std/Code/CFrames.ocf Std/Code/Cmds.ocf Std/Code/Dialog.ocf Std/Code/Interpreter.ocf Std/Code/Links.ocf Std/Code/Loader.ocf Std/Code/Log.ocf Std/Code/MenuTool.ocf System/Code/Containers.ocf System/Code/Controllers.ocf System/Code/Controls.ocf System/Code/Converters.ocf System/Code/Dates.ocf System/Code/Dialog.ocf System/Code/Documents.ocf System/Code/Files.ocf System/Code/Fonts.ocf System/Code/Init.ocf System/Code/Kernel.ocf System/Code/Log.ocf System/Code/Math.ocf System/Code/Mechanisms.ocf System/Code/Meta.ocf System/Code/Models.ocf System/Code/Ports.ocf System/Code/Printers.ocf System/Code/Printing.ocf System/Code/Properties.ocf System/Code/Sequencers.ocf System/Code/Services.ocf System/Code/Stores.ocf System/Code/Strings.ocf System/Code/Views.ocf System/Code/Windows.ocf Text/Code/Cmds.ocf Text/Code/Controllers.ocf Text/Code/Mappers.ocf Text/Code/Models.ocf Text/Code/Rulers.ocf Text/Code/Setters.ocf Text/Code/Views.ocf Unicode/Code/Case_Mapping.ocf Unicode/Code/Letter_Mapping.ocf Util/Code/Alea.ocf Util/Code/AvlTree.ocf Util/Code/BBTree.ocf Util/Code/BTree.ocf Util/Code/Json.ocf Util/Code/Net.ocf Util/Code/Sets.ocf Util/Code/Sort.ocf +Babel/Docu/Compil.odc +Babel/Mod/Compil.odc Cpc/Code/Bitmaps.ocf Cpc/Code/Compressors.ocf Cpc/Code/CompressorsConv.ocf @@ -35,6 +37,7 @@ Ctls/Code/Buttons2.ocf Dev/Code/Browser.ocf Dev/Code/Commanders.ocf Dev/Code/Debug.ocf +Dev/Code/Search.ocf Dev/Rsrc/Strings.odc Dev/Rsrc/fr/Strings.odc Docu/CP-Lang.odc @@ -47,6 +50,8 @@ Duniter0/Docu/Manual.odc Duniter0/Docu/fr/Manual.odc Duniter0/Mod/Basic.odc Duniter0/Mod/Blockchain.odc +Duniter0/Mod/Centralities.odc +Duniter0/Mod/CentralitiesJson.odc Duniter0/Mod/CertificationsPrint.odc Duniter0/Mod/Certifiers.odc Duniter0/Mod/Clock.odc @@ -56,13 +61,13 @@ Duniter0/Mod/IdentitySearch.odc Duniter0/Mod/Members.odc Duniter0/Mod/MembersPrint.odc Duniter0/Mod/ParametersPrint.odc -Duniter0/Mod/SA-Config.odc +Duniter0/Mod/QualitiesJson.odc +Duniter0/Mod/QualitiesSetsArr.odc Duniter0/Mod/Sandbox.odc Duniter0/Mod/SandboxPrint.odc Duniter0/Mod/SentriesPrint.odc -Duniter0/Mod/WotWizard.odc -Duniter0/Mod/WotWizardPrint.odc Duniter0/Mod/WWViews.odc +Duniter0/Mod/WotWizard.odc Duniter0/Rsrc/About.odc Duniter0/Rsrc/Clock.odc Duniter0/Rsrc/Dates.odc @@ -73,6 +78,7 @@ Duniter0/Rsrc/Sources.odc Duniter0/Rsrc/Strings.odc Duniter0/Rsrc/fr/Strings.odc Duniter0/Rsrc/SA-Menus.odc => System/Rsrc/Menus.odc +Duniter0/Rsrc/Version.odc Form/Code/Controllers.ocf Form/Code/Models.ocf Form/Code/Views.ocf @@ -103,6 +109,7 @@ System/Rsrc/fr/Strings.odc Text/Rsrc/Cmds.odc Text/Rsrc/Strings.odc Text/Rsrc/fr/Strings.odc +Util/Bab/Json.odc Util/Code/External.ocf Util/Docu/Alea.odc Util/Docu/AvlTree.odc @@ -114,6 +121,8 @@ Util/Mod/Alea.odc Util/Mod/AvlTree.odc Util/Mod/BBTree.odc Util/Mod/BTree.odc +Util/Mod/Json.odc +Util/Mod/Net.odc Util/Mod/Sets.odc Util/Mod/Sort.odc Util/Rsrc/Json.tbl diff --git a/Standalone version/Documentation/Util/Sets.txt b/Standalone version/Documentation/Util/Sets.txt index 6215352..5b6f247 100644 --- a/Standalone version/Documentation/Util/Sets.txt +++ b/Standalone version/Documentation/Util/Sets.txt @@ -22,18 +22,21 @@ DEFINITION UtilSets; (s1: Set) Diff (s2: Set): Set, NEW; (s1: Set) XOR (s2: Set): Set, NEW; (s: Set) In (e: INTEGER): BOOLEAN, NEW; - (s: Set) NbOfElems (): INTEGER, NEW; (s: Set) IsEmpty (): BOOLEAN, NEW; (s1: Set) Equal (s2: Set): BOOLEAN, NEW; (s1: Set) Subset (s2: Set): BOOLEAN, NEW; (s: Set) NextElem (inc: BOOLEAN; VAR e: INTEGER): BOOLEAN, NEW; - (s: Set) FirstE (OUT e: INTEGER): BOOLEAN, NEW; - (s: Set) NextE (OUT e: INTEGER): BOOLEAN, NEW; - (s: Set) First (OUT min, max: INTEGER): BOOLEAN, NEW; - (s: Set) Next (OUT min, max: INTEGER): BOOLEAN, NEW; (s: Set) Copy (): Set, NEW END; + SetIterator = RECORD + (VAR i: SetIterator) Attach (s: Set), NEW; + (VAR i: SetIterator) First (OUT min, max: INTEGER): BOOLEAN, NEW; + (VAR i: SetIterator) Next (OUT min, max: INTEGER): BOOLEAN, NEW; + (VAR i: SetIterator) FirstE (OUT e: INTEGER): BOOLEAN, NEW; + (VAR i: SetIterator) NextE (OUT e: INTEGER): BOOLEAN, NEW + END; + PROCEDURE NewSet (): Set; END UtilSets. @@ -54,113 +57,127 @@ Number of elements in the set. PROCEDURE (s: Set) Empty NEW -Empties the set s. +Empty the set s. PROCEDURE (s: Set) Full NEW -Returns in s the largest set available: sMin..sMax. +Returnsin s the largest set available: sMin..sMax. PROCEDURE (s: Set) Interval (min, max: INTEGER) NEW -Sets s to the interval min..max. +Set s to the interval min..max. Pre min..max is included in sMin..sMax 20 PROCEDURE (s: Set) Clear (min, max: INTEGER) NEW -Removes the interval min..max from the set s. +Remove the interval min..max from the set s. PROCEDURE (s: Set) Fill (min, max: INTEGER) NEW -Adds the interval min..max to the set s. +Add the interval min..max to the set s. PROCEDURE (s: Set) Incl (e: INTEGER) NEW -Includes the integer e in the set s. +Include the integer e in the set s. PROCEDURE (s: Set) Excl (e: INTEGER) NEW -Excludes the integer e from the set s. +Exclude the integer e from the set s. PROCEDURE (s: Set) Small (se: SET) NEW -Sets s to the Component Pascal SET se. +Set s to the Component Pascal SET se. PROCEDURE (s1: Set) Union (s2: Set): Set NEW -Returns the union of s1 and s2. +Return the union of s1 and s2. Pre s2 # NIL 20 PROCEDURE (s1: Set) Inter (s2: Set): Set NEW -Returns the intersection of s1 and s2. +Return the intersection of s1 and s2. Pre s2 # NIL 20 PROCEDURE (s1: Set) Diff (s2: Set): Set NEW -Returns the difference between s1 and s2. +Return the difference between s1 and s2. Pre s2 # NIL 20 PROCEDURE (s1: Set) XOR (s2: Set): Set NEW -Returns the exclusive union of s1 and s2. +Return the exclusive union of s1 and s2. Pre s2 # NIL 20 PROCEDURE (s: Set) In (e: INTEGER): BOOLEAN NEW -Tests whether the integer e is in the set s. - -PROCEDURE (s: Set) NbOfElems (): INTEGER -NEW -Returns the number of elements in s. +Check whether the integer e is in the set s. PROCEDURE (s: Set) IsEmpty (): BOOLEAN NEW -Tests whether s is empty. +Check whether s is empty. PROCEDURE (s1: Set) Equal (s2: Set): BOOLEAN NEW -Tests whether s1 = s2. +Check whether s1 = s2. PROCEDURE (s1: Set) Subset (s2: Set): BOOLEAN NEW -Tests whether s1 is a subset (in the broad sense of the word) of s2. +Check whether s1 is a subset (in the broad sense of the word) of s2. PROCEDURE (s: Set) NextElem (inc: BOOLEAN; VAR e: INTEGER): BOOLEAN NEW -Replaces e by the next integer e' of s. If inc = TRUE, e' > e; otherwise, e' < e. e may be outside of the interval sMin..sMax, but e' is inside it. Returns TRUE if there is such a successor of e, otherwise e is unchanged. Usage: e := sMin - 1; WHILE s.NextElem(TRUE, e) DO ... END; +Replace e by the next integer e' of s. If inc = TRUE, e' > e; otherwise, e' < e. e may be outside of the interval sMin..sMax, but e' is inside it. Return TRUE if there is such a successor of e, otherwise e is unchanged. Usage: e := sMin - 1; WHILE s.NextElem(TRUE, e) DO ... END; -PROCEDURE (s: Set) FirstE (OUT e: INTEGER): BOOLEAN +PROCEDURE (s: Set) Copy (): Set NEW -On return, e contains the first integer of the set s. Returns TRUE if such an integer exists. Usage: ok := s.FirstE(e); WHILE ok DO ... ok := s.NextE(e) END;. Using FirstE & NextE works faster than using NextElem. +Create and return a copy of s. + +TYPE SetIterator +Iterator of a Set.. + +PROCEDURE (VAR i: SetIterator) Attach (s: Set), NEW; +Attach the set s to i.. -PROCEDURE (s: Set) NextE (OUT e: INTEGER): BOOLEAN +PROCEDURE (VAR i: SetIterator) First (OUT min, max: INTEGER): BOOLEAN NEW -On return, e contains the next integer of the set s. Returns TRUE if such an integer exists. s.FirstE must have been called once before s.NextE. Usage: ok := s.FirstE(e); WHILE ok DO ... ok := s.NextE(e) END;. Using FirstE & NextE works faster than using NextElem. +On return, min and max contain the first interval of the set attached to i. Return TRUE if such an interval exists. Usage: ok := i.First(a, b); WHILE ok DO ... ok := s.Next(a, b) END; -PROCEDURE (s: Set) First (OUT min, max: INTEGER): BOOLEAN +Pre +i has been attached to a Set 20 +i.First was called once before 21 + +PROCEDURE (VAR i: SetIterator) Next (OUT min, max: INTEGER): BOOLEAN NEW -On return, min and max contain the first interval of the set s. Returns TRUE if such an interval exists. Usage: ok := s.First(a, b); WHILE ok DO ... ok := s.Next(a, b) END; +On return, min and max contain the next interval of the set attached to i. Returns TRUE if such an interval exists. i.First must have been called once before i.Next. Usage: ok := i.First(a, b); WHILE ok DO ... ok := i.Next(a, b) END; + +Pre +i has been attached to a Set 20 +i.First was called once before 21 -PROCEDURE (s: Set) Next (OUT min, max: INTEGER): BOOLEAN +PROCEDURE (VAR i: SetIterator) FirstE (OUT e: INTEGER): BOOLEAN NEW -On return, min and max contain the next interval of the set s. Returns TRUE if such an interval exists. s.First must have been called once before s.Next. Usage: ok := s.First(a, b); WHILE ok DO ... ok := s.Next(a, b) END; +On return, e contains the first integer of the set attached to i. Return TRUE if such an integer exists. Usage: ok := i.FirstE(e); WHILE ok DO ... ok := i.NextE(e) END;. Using FirstE & NextE works faster than using NextElem. Pre -s.First was called once before 20 +i has been attached to a Set 20 -PROCEDURE (s: Set) Copy (): Set +PROCEDURE (VAR i: SetIterator) NextE (OUT e: INTEGER): BOOLEAN NEW -Creates and returns a copy of s. +On return, e contains the next integer of the set attached to i. Return TRUE if such an integer exists. i.FirstE must have been called once before i.NextE. Usage: ok := i.FirstE(e); WHILE ok DO ... ok := i.NextE(e) END;. Using FirstE & NextE works faster than using NextElem. + +Pre +i has been attached to a Set 20 +i.First was called once before 21 PROCEDURE NewSet (): Set Creates and returns a new empty set. \ No newline at end of file diff --git a/Standalone version/Help/Explorer.en.png b/Standalone version/Help/Explorer.en.png index 28e505a..c386008 100644 Binary files a/Standalone version/Help/Explorer.en.png and b/Standalone version/Help/Explorer.en.png differ diff --git a/Standalone version/Help/Explorer.fr.png b/Standalone version/Help/Explorer.fr.png index f342c41..b18365a 100644 Binary files a/Standalone version/Help/Explorer.fr.png and b/Standalone version/Help/Explorer.fr.png differ diff --git a/Standalone version/Help/Manual.en.pdf b/Standalone version/Help/Manual.en.pdf index a1f51cb..3aa37da 100644 Binary files a/Standalone version/Help/Manual.en.pdf and b/Standalone version/Help/Manual.en.pdf differ diff --git a/Standalone version/Help/Manual.fr.pdf b/Standalone version/Help/Manual.fr.pdf index ba68d53..1c6aae4 100644 Binary files a/Standalone version/Help/Manual.fr.pdf and b/Standalone version/Help/Manual.fr.pdf differ diff --git a/Standalone version/Sources/Duniter0/Basic.txt b/Standalone version/Sources/Duniter0/Basic.txt index 6d158f7..f512a39 100644 --- a/Standalone version/Sources/Duniter0/Basic.txt +++ b/Standalone version/Sources/Duniter0/Basic.txt @@ -76,8 +76,10 @@ MODULE Duniter0Basic; BEGIN (*TimestampToString*) IF t = never THEN Dialog.MapString("#Duniter0:Never", dt); - ELSIF (t = missing) OR (t = revoked) THEN + ELSIF t = missing THEN Dialog.MapString("#Duniter0:Missing", dt); + ELSIF t = revoked THEN + Dialog.MapString("#Duniter0:Revoked", dt); ELSE TimestampToDate(t, date, time); Dates.DateToString(date, Dates.short, da); diff --git a/Standalone version/Sources/Duniter0/Blockchain.txt b/Standalone version/Sources/Duniter0/Blockchain.txt index b56c1cc..bf3a08d 100644 --- a/Standalone version/Sources/Duniter0/Blockchain.txt +++ b/Standalone version/Sources/Duniter0/Blockchain.txt @@ -60,8 +60,6 @@ MODULE Duniter0Blockchain; TYPE - IsFree* = PROCEDURE (IN p: Pubkey): BOOLEAN; - UpdateProc* = PROCEDURE; (* Procedure called at every update *) UpdateList = POINTER TO RECORD (* Chained list of procedures called at every update *) @@ -106,13 +104,14 @@ MODULE Duniter0Blockchain; (* Types of elements in UndoList *) timeList = 0; - addIdList = 1; - removeIdList = 2; - joinList = 3; - activeList = 4; - leaveList = 5; - certAddList = 6; - certRemoveList = 7; + idAddList = 1; + joinList = 2; + activeList = 3; + leaveList = 4; + idAddTimeList = 5; + idRemoveTimeList = 6; + certAddList = 7; + certRemoveList = 8; hasNotLeaved* = -1; @@ -266,12 +265,9 @@ MODULE Duniter0Blockchain; VAR - isFree: IsFree; - duniBase-: Files.Name; (* Path to the Duniter database *) - updateList, (* Head of general UpdateList *) - shortUpdateList: UpdateList; (* Head of short UpdateList *) + updateList: UpdateList; (* Head of general UpdateList *) update: UpdateAction; pars-: Parameters; (* Duniter parmeters *) @@ -290,6 +286,7 @@ MODULE Duniter0Blockchain; (* Sentries & Distance Rule *) members: MembersFind; sentriesS: U.Set; (* Set of sentries *) + sentriesI: U.SetIterator; (* Iterator of sentriesS *) poST: A.Tree; undoList: INTEGER; (* Head of UndoList *) @@ -1337,9 +1334,9 @@ MODULE Duniter0Blockchain; BEGIN (*NextSentry*) IF first THEN - b := sentriesS.FirstE(sentryCur); + b := sentriesI.FirstE(sentryCur); ELSE - b := sentriesS.NextE(sentryCur); + b := sentriesI.NextE(sentryCur); END; IF ~b THEN RETURN FALSE; @@ -1352,22 +1349,22 @@ MODULE Duniter0Blockchain; PROCEDURE SentriesLen* (): INTEGER; BEGIN (*SentriesLen*) - RETURN sentriesS.NbOfElems(); + RETURN sentriesS.nbElems; END SentriesLen; (* Array of certifiers' pubkeys -> % of sentries reached in pars.stepMax - 1 steps *) - PROCEDURE PercentOfSentries* (pubkeys: Pubkeys): REAL; + PROCEDURE PercentOfSentries* (IN pubkeys: ARRAY OF Pubkey): REAL; VAR set, frontier, newFrontier: U.Set; + frontierI: U.SetIterator; e, i: INTEGER; ok: BOOLEAN; poS: REAL; poSE: PoSE; - ee: A.Elem; - PROCEDURE Sort (pubkeys: Pubkeys); + PROCEDURE Sort (pubkeys: ARRAY OF Pubkey); VAR @@ -1386,37 +1383,44 @@ MODULE Duniter0Blockchain; END; END Sort; - PROCEDURE Find (pubkeys: Pubkeys; OUT poS: REAL): BOOLEAN; + PROCEDURE Find (poSE: PoSE; OUT poS: REAL): BOOLEAN; VAR n: INTEGER; + e: A.Elem; BEGIN (*Find*) - IF ~poST.Search(ee, n) THEN + e := poSE; + IF ~poST.Search(e, n) THEN RETURN FALSE; END; - poS := ee(PoSE).poS; + poS := e(PoSE).poS; RETURN TRUE; END Find; - PROCEDURE Store (pubkeys: Pubkeys; poS: REAL); + PROCEDURE Store (poSE: PoSE; poS: REAL); VAR b: BOOLEAN; n: INTEGER; + e: A.Elem; BEGIN (*Store*) poSE.poS := poS; - b := poST.SearchIns(ee, n); ASSERT(~b, 100); + e := poSE; + b := poST.SearchIns(e, n); ASSERT(~b, 100); END Store; BEGIN (*PercentOfSentries*) Sort(pubkeys); - NEW(poSE); ee := poSE; - poSE.pubkeys := pubkeys; - IF ~Find(pubkeys, poS) THEN + NEW(poSE); + NEW(poSE.pubkeys, LEN(pubkeys)); + FOR i := 0 TO LEN(pubkeys) - 1 DO + poSE.pubkeys[i] := pubkeys[i]; + END; + IF ~Find(poSE, poS) THEN set := U.NewSet(); frontier := U.NewSet(); FOR i := 0 TO LEN(pubkeys) - 1 DO @@ -1427,22 +1431,23 @@ MODULE Duniter0Blockchain; END; FOR i := 1 TO pars.stepMax - 1 DO newFrontier := U.NewSet(); - ok := frontier.FirstE(e); + frontierI.Attach(frontier); + ok := frontierI.FirstE(e); WHILE ok DO newFrontier := newFrontier.Union(members.m[e].links); - ok := frontier.NextE(e); + ok := frontierI.NextE(e); END; frontier := newFrontier; set := set.Union(frontier); END; - poS := set.Inter(sentriesS).NbOfElems() / sentriesS.NbOfElems(); - Store(pubkeys, poS); + poS := set.Inter(sentriesS).nbElems / sentriesS.nbElems; + Store(poSE, poS); END; RETURN poS; END PercentOfSentries; (* Verify the distance rule for a set of certifiers' pubkeys *) - PROCEDURE DistanceRuleOk* (pubkeys: Pubkeys): BOOLEAN; + PROCEDURE DistanceRuleOk* (IN pubkeys: ARRAY OF Pubkey): BOOLEAN; BEGIN (*DistanceRuleOk*) RETURN PercentOfSentries(pubkeys) >= pars.xpercent; @@ -1555,43 +1560,17 @@ MODULE Duniter0Blockchain; rNow := MAX(rNow, t.time); END Times; - PROCEDURE RemoveId (withList: BOOLEAN; p: Pubkey); - - VAR - - idP: PubKey; - b: BOOLEAN; - idRef: INTEGER; - id: Identity; - idU: B.String; - idL: UndoList; (* leaversList *) - - BEGIN (*RemoveId*) - NEW(idP); idP.ref := p; - IF ~certFromT.Search(idP) & ~certToT.Search(idP) & isFree(p) THEN - b := idPubT.Search(idP); ASSERT(b, 100); - idRef := idPubT.ReadValue(); - id := idMan.ReadData(idRef)(Identity); - IF id.expires_on # BA.revoked THEN - b := idPubT.Erase(idP); ASSERT(b, 101); - NEW(idU); idU.c := id.uid; - b := idUidT.Erase(idU); ASSERT(b, 102); - IF withList THEN - NEW(idL); idL.next := undoList; idL.type := removeIdList; idL.ref := idRef; idL.aux := 0; - undoList := undoListMan.WriteAllocateData(idL); - ELSE - idMan.EraseData(idRef); - END; - END; - END; - END RemoveId; - (* For one block, add joining & leaving identities in joinAndLeaveT and updade identities in idPubT and idUidT; update certFromT & certToT too *) + (* + - Le membre demande à partir ; il passe par les champs leavers et excluded ; ses éléments d'identité (uid et clé publique) peuvent être réutilisés par lui-même mais pas par d'autres. + - Le membre révoque son identité explicitement ; champs revoked et excluded ; ses éléments d'identité sont bloqués à jamais. + - Le membre ne renouvelle pas son appartenance dans les temps ; champ excluded uniquement ; au bout d'un an, ses éléments d'identité sont bloqués à jamais (mais il n'apparaît dans aucun champ supplémentaire). + *) PROCEDURE Identities (withList: BOOLEAN; IN ssJ, ssA, ssL, ssR, ssE, nb: ARRAY OF CHAR; t: S.Table); VAR - i, idRef, jlRef, n, res: INTEGER; + i, idRef, jlRef, n, res, bnb: INTEGER; tt: LONGINT; s: ARRAY 101 OF CHAR; b: BOOLEAN; @@ -1636,6 +1615,7 @@ MODULE Duniter0Blockchain; END; ASSERT(id.hash # "", 104); Strings.StringToInt(nb, id.block_number, res); ASSERT(res = 0, 105); + bnb := id.block_number; NEW(idU); NEW(idU.c, LEN(id.uid$) + 1); idU.c^ := id.uid$; NEW(idP); idP.ref := id.pubkey; IF idPubT.SearchIns(idP) THEN @@ -1658,7 +1638,7 @@ MODULE Duniter0Blockchain; b := idUidT.SearchIns(idU); ASSERT(~b, 109); idUidT.WriteValue(idRef); IF withList THEN - NEW(idL); idL.next := undoList; idL.type := addIdList; idL.ref := idRef; idL.aux := 0; + NEW(idL); idL.next := undoList; idL.type := idAddList; idL.ref := idRef; idL.aux := 0; undoList := undoListMan.WriteAllocateData(idL); END; END; @@ -1674,7 +1654,7 @@ MODULE Duniter0Blockchain; END; NEW(jlL); jlL.next := jl .list; - jlL.joiningBlock := id.block_number; + jlL.joiningBlock := bnb; jlL.leavingBlock := hasNotLeaved; jl.list := joinAndLeaveLMan.WriteAllocateData(jlL); joinAndLeaveMan.WriteData(jlRef, jl); @@ -1685,7 +1665,7 @@ MODULE Duniter0Blockchain; END; i := 1; - WHILE ssA[i] # ']' DO (* actives : Update *) + WHILE ssA[i] # ']' DO (* actives *) INC(i); NEW(idP); ScanS(ssA, ':', idP.ref, i); @@ -1709,7 +1689,7 @@ MODULE Duniter0Blockchain; END; i := 1; - WHILE ssL[i] # ']' DO (* leavers : Remove id *) + WHILE ssL[i] # ']' DO (* leavers *) INC(i); NEW(idP); ScanS(ssL, ':', idP.ref, i); @@ -1729,7 +1709,7 @@ MODULE Duniter0Blockchain; END; i := 1; - WHILE ssR[i] # ']' DO (* revoked : Remove id *) + WHILE ssR[i] # ']' DO (* revoked *) INC(i); NEW(idP); ScanS(ssR, ':', idP.ref, i); @@ -1744,12 +1724,12 @@ MODULE Duniter0Blockchain; NEW(idL); idL.next := undoList; idL.type := activeList; idL.ref := idRef; idL.aux := id.expires_on; undoList := undoListMan.WriteAllocateData(idL); END; - id.expires_on := BA.revoked; (* BA.revoked? pour ne pas l'effacer ? *) + id.expires_on := BA.revoked; idMan.WriteData(idRef, id); END; i := 1; - WHILE ssE[i] # ']' DO (* excluded : Remove id *) + WHILE ssE[i] # ']' DO (* excluded *) INC(i); DEC(idLenM); NEW(idP); @@ -1774,18 +1754,18 @@ MODULE Duniter0Blockchain; NEW(idL); idL.next := undoList; idL.type := leaveList; idL.ref := idRef; idL.aux := 0; undoList := undoListMan.WriteAllocateData(idL); END; - IF id.expires_on = BA.missing THEN - RemoveId(withList, idP.ref); - ELSIF id.expires_on # BA.revoked THEN + IF (id.expires_on # BA.missing) & (id.expires_on # BA.revoked) THEN IF withList THEN NEW(idL); idL.next := undoList; idL.type := activeList; idL.ref := idRef; idL.aux := id.expires_on; undoList := undoListMan.WriteAllocateData(idL); END; INC(id.expires_on, pars.msValidity); idMan.WriteData(idRef, id); - IF ~certFromT.Search(idP) & ~certToT.Search(idP) & isFree(idP.ref) THEN - NEW(iK); iK.ref := idRef; - b := idTimeT.SearchIns(iK); ASSERT(~b, 121); + NEW(iK); iK.ref := idRef; + b := idTimeT.SearchIns(iK); ASSERT(~b, 121); + IF withList THEN + NEW(idL); idL.next := undoList; idL.type := idAddTimeList; idL.ref := idRef; idL.aux := 0; + undoList := undoListMan.WriteAllocateData(idL); END; END; END; @@ -1924,12 +1904,33 @@ MODULE Duniter0Blockchain; ELSE certMan.EraseData(pC); END; - RemoveId(withList, c.from); - RemoveId(withList, c.to); END; END RemoveExpiredCerts; - PROCEDURE RemoveExpiredIds (now, secureNow: LONGINT); + PROCEDURE RevokeId (withList: BOOLEAN; p: Pubkey); + + VAR + + idP: PubKey; + b: BOOLEAN; + idRef: INTEGER; + id: Identity; + idL: UndoList; (* leaversList *) + + BEGIN (*RevokeId*) + NEW(idP); idP.ref := p; + b := idPubT.Search(idP); ASSERT(b, 100); + idRef := idPubT.ReadValue(); + id := idMan.ReadData(idRef)(Identity); + IF withList THEN + NEW(idL); idL.next := undoList; idL.type := activeList; idL.ref := idRef; idL.aux := id.expires_on; + undoList := undoListMan.WriteAllocateData(idL); + END; + id.expires_on := BA.revoked; + idMan.WriteData(idRef, id); + END RevokeId; + + PROCEDURE RevokeExpiredIds (now, secureNow: LONGINT); VAR @@ -1937,8 +1938,9 @@ MODULE Duniter0Blockchain; iK: IntKey; b, withList: BOOLEAN; pId: INTEGER; + idL: UndoList; - BEGIN (*RemoveExpiredIds*) + BEGIN (*RevokeExpiredIds*) NEW(id); id.expires_on := now; id.pubkey := ""; NEW(id.uid, 1); id.uid^ := ""; pId := idMan.WriteAllocateData(id); NEW(iK); iK.ref := pId; @@ -1951,9 +1953,13 @@ MODULE Duniter0Blockchain; iK.ref := pId; b := idTimeT.Erase(iK); ASSERT(b, 100); withList := id.expires_on >= secureNow; - RemoveId(withList, id.pubkey); + IF withList THEN + NEW(idL); idL.next := undoList; idL.type := idRemoveTimeList; idL.ref := pId; idL.aux := 0; + undoList := undoListMan.WriteAllocateData(idL); + END; + RevokeId(withList, id.pubkey); END; - END RemoveExpiredIds; + END RevokeExpiredIds; (* Undo the last operations done from the secureGap last blocks *) PROCEDURE RemoveSecureGap; @@ -1983,7 +1989,7 @@ MODULE Duniter0Blockchain; NEW(i); i.ref := t.bnb; b := timeT.Erase(i); ASSERT(b, 100); timeMan.EraseData(l.ref); - |addIdList: + |idAddList: (* Erase the Identity data pointed by l.ref and the corresponding keys in idPubT and idUidT *) id := idMan.ReadData(l.ref)(Identity); NEW(p); p.ref := id.pubkey; @@ -1991,15 +1997,6 @@ MODULE Duniter0Blockchain; NEW(u); u.c := id.uid; b := idUidT.Erase(u); ASSERT(b, 102); idMan.EraseData(l.ref); - |removeIdList: - (* Insert the keys corresponding to the Identity pointed by l.ref into idPubT and idUidT *) - id := idMan.ReadData(l.ref)(Identity); - NEW(p); p.ref := id.pubkey; - b := idPubT.SearchIns(p); ASSERT(~b, 103); - idPubT.WriteValue(l.ref); - NEW(u); u.c := id.uid; - b := idUidT.SearchIns(u); ASSERT(~b, 104); - idUidT.WriteValue(l.ref); |joinList: (* Erase the last JoinAndLeaveL data corresponding to l.ref; if this is also the first data, erase the corresponding JoinAndLeave data and its key in joinAndLeaveT *) id := idMan.ReadData(l.ref)(Identity); @@ -2040,12 +2037,18 @@ MODULE Duniter0Blockchain; ASSERT(jlL.leavingBlock # hasNotLeaved, 109); jlL.leavingBlock := hasNotLeaved; joinAndLeaveLMan.WriteData(jl.list, jlL); + |idAddTimeList: + NEW(i); i.ref := l.ref; + b := idTimeT.Erase(i); ASSERT(b, 110); + |idRemoveTimeList: + NEW(i); i.ref := l.ref; + b := idTimeT.SearchIns(i); ASSERT(~b, 111); |certAddList: (* Erase the keys corresponding to the certification pointed by l.ref in certFromT and certToT *) c := certMan.ReadData(l.ref)(Certification); RemoveCert(c); NEW(i); i.ref := l.ref; - b := certTimeT.Erase(i); ASSERT(b, 110); + b := certTimeT.Erase(i); ASSERT(b, 112); certMan.EraseData(l.ref); |certRemoveList: (* Insert the keys corresponding to the Certification pointed by l.ref into certFromT, certToT and certTimeT *) @@ -2060,7 +2063,7 @@ MODULE Duniter0Blockchain; END; p.ref := c.to; ind := database.OpenIndex(n, pubKeyMan, pubKeyFac); - b := ind.SearchIns(p); ASSERT(~b, 111); + b := ind.SearchIns(p); ASSERT(~b, 113); ind.WriteValue(l.ref); ind.Close; IF certToT.SearchIns(p) THEN @@ -2071,11 +2074,11 @@ MODULE Duniter0Blockchain; END; p.ref := c.from; ind := database.OpenIndex(n, pubKeyMan, pubKeyFac); - b := ind.SearchIns(p); ASSERT(~b, 113); + b := ind.SearchIns(p); ASSERT(~b, 114); ind.WriteValue(l.ref); ind.Close; NEW(i); i.ref := l.ref; - b := certTimeT.SearchIns(i); ASSERT(~b, 114); + b := certTimeT.SearchIns(i); ASSERT(~b, 115); END; undoListMan.EraseData(undoList); undoList := l.next; @@ -2114,7 +2117,7 @@ MODULE Duniter0Blockchain; END; END; - sentriesS := U.NewSet(); + sentriesS := U.NewSet(); sentriesI.Attach(sentriesS); n := IdLenM(); IF n = 0 THEN RETURN END; n := SHORT(ENTIER(Math.Ceiling(Math.Power(n, 1 / pars.stepMax)))); @@ -2176,7 +2179,7 @@ MODULE Duniter0Blockchain; END; Strings.StringToLInt(cur.fields[1], secureNow, res); ASSERT(res = 0, 105); END; - RemoveExpiredIds(now, secureNow); + RevokeExpiredIds(now, secureNow); RemoveExpiredCerts(now, secureNow); (* Élimine toutes les certifications expirées avec réversibilité dans secureGap *) END; database.WritePlace(undoListPlace, undoList); @@ -2193,18 +2196,14 @@ MODULE Duniter0Blockchain; END; END ScanBlocks; - PROCEDURE AddUpdateProc* (updateProc: UpdateProc; short: BOOLEAN); + PROCEDURE AddUpdateProc* (updateProc: UpdateProc); VAR l, m: UpdateList; BEGIN (*AddUpdateProc*) - IF short THEN - l := shortUpdateList; - ELSE - l := updateList; - END; + l := updateList; m := NIL; WHILE l # NIL DO m := l; @@ -2214,28 +2213,20 @@ MODULE Duniter0Blockchain; l.next := NIL; l.update := updateProc; IF m = NIL THEN - IF short THEN - shortUpdateList := l; - ELSE - updateList := l; - END; + updateList := l; ELSE m.next := l; END; END AddUpdateProc; - PROCEDURE RemoveUpdateProc* (updateProc: UpdateProc; short: BOOLEAN); + PROCEDURE RemoveUpdateProc* (updateProc: UpdateProc); VAR l, m: UpdateList; BEGIN (*RemoveUpdateProc*) - IF short THEN - l := shortUpdateList; - ELSE - l := updateList; - END; + l := updateList; m := NIL; WHILE (l # NIL) & (l.update # updateProc) DO m := l; @@ -2243,11 +2234,7 @@ MODULE Duniter0Blockchain; END; ASSERT(l # NIL, 20); IF m = NIL THEN - IF short THEN - shortUpdateList := l.next; - ELSE - updateList := l.next; - END; + updateList := l.next; ELSE m.next := l.next; END; @@ -2279,21 +2266,6 @@ MODULE Duniter0Blockchain; Params(d); END Scan1; - PROCEDURE Update*; - - VAR - - l: UpdateList; - - BEGIN (*Update*) - l := shortUpdateList; - WHILE l # NIL DO - l.update; - l := l.next; - END; - BA.Collect; - END Update; - PROCEDURE UpdateAll*; VAR @@ -2406,12 +2378,6 @@ MODULE Duniter0Blockchain; END; END ResetDataBase; - PROCEDURE FixIsFree* (if: IsFree); - - BEGIN (*FixIsFree*) - isFree := if; - END FixIsFree; - PROCEDURE Init; VAR @@ -2424,7 +2390,6 @@ MODULE Duniter0Blockchain; f: TextMappers.Formatter; BEGIN (*Init*) - isFree := NIL; duniBase := ''; l := Files.dir.This(initDir); ASSERT(l.res = 0, 100); REPEAT @@ -2455,8 +2420,7 @@ MODULE Duniter0Blockchain; Scan1; delay := pars.avgGenTime * Services.resolution; updateList := NIL; - AddUpdateProc(Scan, TRUE); - AddUpdateProc(Scan, FALSE); + AddUpdateProc(Scan); NEW(undoListFac); NEW(timeFac); NEW(joinAndLeaveLFac); NEW(joinAndLeaveFac); NEW(identityFac); NEW(certificationFac); NEW(intKeyFac); NEW(uidKeyFac); NEW(pubKeyFac); @@ -2464,7 +2428,7 @@ MODULE Duniter0Blockchain; NEW(intKeyMan); NEW(idKTimeMan); NEW(certKTimeMan); OpenB; NEW(update); - Update; + UpdateAll; END Init; BEGIN (*Duniter0Blockchain*) diff --git a/Standalone version/Sources/Duniter0/Centralities.txt b/Standalone version/Sources/Duniter0/Centralities.txt new file mode 100644 index 0000000..c035b7f --- /dev/null +++ b/Standalone version/Sources/Duniter0/Centralities.txt @@ -0,0 +1,212 @@ +(* +Duniter0: WotWizard. + +Copyright (C) 2017 GérardMeunier + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +MODULE Duniter0Centralities; + + (* Le degré de centralité d'un membre est le nombre de couples orientés (membre->membre) pour lesquels il fait partie d'un des plus courts chemins reliant ce couple. *) + + + + IMPORT + + A := UtilAvlTree, BA := Duniter0Basic, B := Duniter0Blockchain, N := UtilNet, Math, UtilSort; + + TYPE + + Net = POINTER TO RECORD (N.Net) + END; + + Node = POINTER TO RECORD (N.Node) + p: B.Pubkey; + pos: B.CertPos; + END; + + Central* = POINTER TO RECORD + id-: B.String; + c-: REAL; + END; + + Centrals* = POINTER TO ARRAY OF Central; + + CentralSort = EXTENSIBLE RECORD (UtilSort.T) + c: Centrals + END; + + CentralSortId = RECORD (CentralSort) + END; + + VAR + + net: Net; + + PROCEDURE (VAR s: CentralSort) Swap (p1, p2: INTEGER); + + VAR + + c: Central; + + BEGIN (*Swap*) + c := s.c[p1]; s.c[p1] := s.c[p2]; s.c[p2] := c; + END Swap; + + PROCEDURE (VAR s: CentralSort) Less (p1, p2: INTEGER): BOOLEAN, EXTENSIBLE; + + BEGIN (*Less*) + RETURN (s.c[p1].c > s.c[p2].c) OR (s.c[p1].c = s.c[p2].c) & (BA.CompP(s.c[p1].id, s.c[p2].id) = A.lt); + END Less; + + PROCEDURE (VAR s: CentralSortId) Less (p1, p2: INTEGER): BOOLEAN; + + BEGIN (*Less*) + RETURN BA.CompP(s.c[p1].id, s.c[p2].id) = A.lt; + END Less; + + PROCEDURE NewNode (IN p: B.Pubkey): Node; + + VAR + + n: Node; + + BEGIN (*NewNode*) + NEW(n); + n.p := p; + RETURN n; + END NewNode; + + PROCEDURE (net: Net) Number (): INTEGER; + + BEGIN (*Number*) + RETURN B.IdLen(); + END Number; + + PROCEDURE (net: Net) Enumerate (first: BOOLEAN; OUT node: N.Node; OUT member: BOOLEAN): BOOLEAN; + + VAR + + p: B.Pubkey; + id: B.String; + b: BOOLEAN; + h: B.Hash; + bnb: INTEGER; + exp: LONGINT; + + BEGIN (*Enumerate*) + IF B.IdNextUid(first, id) THEN + b := B.IdUidComplete(id, p, member, h, bnb, exp); ASSERT(b); + node := NewNode(p); + RETURN TRUE; + END; + RETURN FALSE; + END Enumerate; + + PROCEDURE (n1: Node) Compare (n2: N.Node): BYTE; + + BEGIN (*Compare*) + WITH n2: Node DO + IF n1.p < n2.p THEN + RETURN A.lt; + END; + IF n1.p > n2.p THEN + RETURN A.gt; + END; + RETURN A.eq; + END; + END Compare; + + PROCEDURE (n: Node) FromTo (first: BOOLEAN; OUT follow: N.Node): BOOLEAN; + + VAR + + b: BOOLEAN; + from, to: B.Pubkey; + + BEGIN (*FromTo*) + IF first THEN + b := B.CertFrom(n.p, n.pos); + END; + IF ~n.pos.CertNextPos(from, to) THEN + RETURN FALSE; + END; + follow := NewNode(to); + RETURN TRUE; + END FromTo; + + PROCEDURE Count* (OUT centers, centersId: Centrals); + + VAR + + i, len: INTEGER; + ok, b: BOOLEAN; + c: Central; + s: CentralSort; + sId: CentralSortId; + cV: LONGINT; + id: B.String; + cT: N.Centrals; + node: N.Node; + max: REAL; + + BEGIN (*Count*) + cT := net.Centralities(); + len := net.ExtremitiesNb(); + max := Math.Ln(1 + (len - 1) * (len - 2)); + NEW(centers, len); + i := 0; + ok := cT.Walk(TRUE, node, cV); + WHILE ok DO + WITH node: Node DO + b := B.IdPub(node.p, id); ASSERT(b); + NEW(c); + c.id := id; + c.c := Math.Ln(1 + cV) / max; + centers[i] := c; + INC(i); + END; + ok := cT.Walk(FALSE, node, cV); + END; + ASSERT(i = len); + s.c := centers; + s.QuickSort(0, len - 1); + NEW(centersId, len); + FOR i := 0 TO len - 1 DO + centersId[i] := centers[i]; + END; + sId.c := centersId; + sId.QuickSort(0, len - 1); + END Count; + + PROCEDURE CountOne* (p: B.Pubkey): REAL; + + VAR + + len: LONGINT; + + BEGIN (*CountOne*) + len := net.ExtremitiesNb(); + RETURN Math.Ln(1 + net.Centrality(NewNode(p))) / Math.Ln(1 + (len - 1) * (len - 2)); + END CountOne; + + PROCEDURE Update; + + BEGIN (*Update*) + net.Update; + END Update; + + BEGIN (*Duniter0Centralities*) + NEW(net); + B.AddUpdateProc(Update); + B.UpdateAll; + CLOSE + B.RemoveUpdateProc(Update); + END Duniter0Centralities. + +DevDebug.UnloadThis Duniter0CentralitiesPrint Duniter0Centralities UtilNet diff --git a/Standalone version/Sources/Duniter0/CentralitiesJson.txt b/Standalone version/Sources/Duniter0/CentralitiesJson.txt new file mode 100644 index 0000000..04cbdd1 --- /dev/null +++ b/Standalone version/Sources/Duniter0/CentralitiesJson.txt @@ -0,0 +1,59 @@ +(* +Duniter0: WotWizard. + +Copyright (C) 2017 GérardMeunier + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +MODULE Duniter0CentralitiesJson; + + + + IMPORT + + B := Duniter0Blockchain, C := Duniter0Centralities, J := UtilJson, TextMappers, TextModels, TextViews, Views; + + PROCEDURE Print*; + + VAR + + centers, centersId: C.Centrals; + i: INTEGER; + t: TextModels.Model; + f: TextMappers.Formatter; + + BEGIN (*Print*) + C.Count(centers, centersId); + J.StartObject; + J.PushString("Centralities"); + J.BuildField("description"); + J.PushInteger(B.LastBlock()); + J.BuildField("block"); + J.StartArray; + FOR i := 0 TO LEN(centersId) - 1 DO + J.StartObject; + J.PushString(centersId[i].id); + J.BuildField("id"); + J.PushReal(centersId[i].c); + J.BuildField("centrality"); + J.BuildObject; + END; + J.BuildArray; + J.BuildField("values"); + J.BuildObject; + t := TextModels.dir.New(); + f.ConnectTo(t); + J.GetJson().Write(f); + Views.OpenView(TextViews.dir.New(t)); + END Print; + + END Duniter0CentralitiesJson. + +DevDebug.UnloadThis Duniter0CentralitiesPrint Duniter0CentralitiesJson Duniter0Centralities + +Duniter0CentralitiesJson.Print; diff --git a/Standalone version/Sources/Duniter0/Clock.txt b/Standalone version/Sources/Duniter0/Clock.txt index b725feb..5ba705c 100644 --- a/Standalone version/Sources/Duniter0/Clock.txt +++ b/Standalone version/Sources/Duniter0/Clock.txt @@ -71,11 +71,11 @@ MODULE Duniter0Clock; BEGIN (*Init*) oldBlock := - 1; UpdateTime; - B.AddUpdateProc(UpdateTime, FALSE); + B.AddUpdateProc(UpdateTime); END Init; BEGIN (*Duniter0Clock*) Init; CLOSE - B.RemoveUpdateProc(UpdateTime, FALSE); + B.RemoveUpdateProc(UpdateTime); END Duniter0Clock. diff --git a/Standalone version/Sources/Duniter0/IdentitySearch.txt b/Standalone version/Sources/Duniter0/IdentitySearch.txt index 7a1866b..07a8007 100644 --- a/Standalone version/Sources/Duniter0/IdentitySearch.txt +++ b/Standalone version/Sources/Duniter0/IdentitySearch.txt @@ -17,17 +17,18 @@ MODULE Duniter0IdentitySearch; IMPORT (* - StdLog, + L := StdLog, *) - A := UtilAvlTree, B := Duniter0Blockchain, Dialog, S := Duniter0Sandbox, BA := Duniter0Basic, Strings; + A := UtilAvlTree, B := Duniter0Blockchain, Dialog, S := Duniter0Sandbox, BA := Duniter0Basic, C := Duniter0Centralities, Strings; CONST maxItems = 100; - nonEditableNb = 10; + nonEditableNb = 12; + oldIcon = '×'; futureIcon = 'º'; TYPE @@ -35,7 +36,8 @@ MODULE Duniter0IdentitySearch; IdE = POINTER TO RECORD (A.Elem) uid: BA.String; hash: B.Hash; - future: BOOLEAN; + future, + active: BOOLEAN; END; NonEditable* = ARRAY 2 * nonEditableNb OF Dialog.String; @@ -58,8 +60,12 @@ MODULE Duniter0IdentitySearch; ring: RingHd; + identityOldNb-, identityNb-, identityFutNb-: INTEGER; + identityDispOld*, + identityDispMem*, + identityDispFut*: BOOLEAN; identityList*: Dialog.List; identityHash: POINTER TO ARRAY OF S.Hash; @@ -67,8 +73,10 @@ MODULE Duniter0IdentitySearch; member-, sentry-, calcDist*, - distanceOK-: BOOLEAN; - fields*: NonEditable; (* uid (0), pubkey (1), limit date (2), limit date of received cert (3), limit date of sent cert (4), hash (5), proportionOfSentries (6), availability (7), inscriptionBlock (8), inscriptionDate (9) *) + distanceOK-, + calcQual*, + calcCentr*: BOOLEAN; + fields*: NonEditable; (* uid (0), pubkey (1), limit date (2), limit date of received cert (3), limit date of sent cert (4), hash (5), proportionOfSentries (6), availability (7), inscriptionBlock (8), inscriptionDate (9), quality (10), centrality (11) *) END; receivedCertsNb-, @@ -200,14 +208,14 @@ MODULE Duniter0IdentitySearch; END; END UpdateCombo; - PROCEDURE Find (IN hint: ARRAY OF CHAR; OUT nA, nF: INTEGER): A.Tree; + PROCEDURE Find (IN hint: ARRAY OF CHAR; OUT nO, nA, nF: INTEGER): A.Tree; VAR t: A.Tree; idE: IdE; e: A.Elem; - b, ok, member: BOOLEAN; + b, ok, active: BOOLEAN; uid: BA.String; pub, p: B.Pubkey; hash: S.Hash; @@ -219,37 +227,61 @@ MODULE Duniter0IdentitySearch; A.New(t); hintD := BA.ToDown(hint); B.IdPosUid(hintD); - ok := B.IdNextUidM(FALSE, uid); + nO := 0; nA := 0; + ok := B.IdNextUid(FALSE, uid); WHILE ok DO ok := BA.Prefix(hintD, uid); - IF ok & B.IdUidComplete(uid, p, member, hash, bloc, exp) THEN - NEW(idE); idE.uid := uid; idE.hash := hash; idE.future := FALSE; e := idE; - b := t.SearchIns(e, n); ASSERT(~b); - ok := B.IdNextUidM(FALSE, uid); + IF ok & B.IdUidComplete(uid, p, active, hash, bloc, exp) THEN + IF (identityDispOld & ~active) OR (identityDispMem & active) THEN + NEW(idE); idE.uid := uid; idE.hash := hash; idE.future := FALSE; idE.active := active; + e := idE; + b := t.SearchIns(e, n); ASSERT(~b); + END; + IF active THEN + INC(nA); + ELSE + INC(nO); + END; + ok := B.IdNextUid(FALSE, uid); END; END; IF LEN(hint$) <= B.pubkeyLen THEN pub := hint$; B.IdPosPubkey(pub); - ok := B.IdNextPubkeyM(FALSE, p); + ok := B.IdNextPubkey(FALSE, p); WHILE ok DO Strings.Find(p, hint, 0, pos); ok := pos = 0; - IF ok & B.IdPubComplete(p, uid, member, hash, bloc, exp) THEN - NEW(idE); idE.uid := uid; idE.hash := hash; idE.future := FALSE; e := idE; - b := t.SearchIns(e, n); - ok := B.IdNextPubkeyM(FALSE, p); + IF ok & B.IdPubComplete(p, uid, active, hash, bloc, exp) THEN + NEW(idE); idE.uid := uid; idE.hash := hash; idE.future := FALSE; idE.active := active; + e := idE; + b := (identityDispOld & ~active) OR (identityDispMem & active); + IF b THEN + b := ~t.SearchIns(e, n); + END; + IF b THEN + IF active THEN + INC(nA); + ELSE + INC(nO); + END; + END; + ok := B.IdNextPubkey(FALSE, p); END; END; END; - nA := t.NumberOfElems(); + nF := 0; S.IdPosUid(hintD); ok := S.IdNextUid(FALSE, uid, hash); WHILE ok DO ok := BA.Prefix(hintD, uid); IF ok THEN - NEW(idE); idE.uid := uid; idE.hash := hash; idE.future := TRUE; e := idE; - b := t.SearchIns(e, n); ASSERT(~b); + NEW(idE); idE.uid := uid; idE.hash := hash; idE.future := TRUE; idE.active := FALSE; + e := idE; + IF identityDispFut THEN + b := t.SearchIns(e, n); ASSERT(~b); + END; + INC(nF); ok := S.IdNextUid(FALSE, uid, hash); END; END; @@ -260,13 +292,19 @@ MODULE Duniter0IdentitySearch; Strings.Find(p, hint, 0, pos); ok := pos = 0; IF ok & S.IdHash(hash, p, uid, exp) THEN - NEW(idE); idE.uid := uid; idE.hash := hash; idE.future := TRUE; e := idE; - b := t.SearchIns(e, n); + NEW(idE); idE.uid := uid; idE.hash := hash; idE.future := TRUE; idE.active := FALSE; + e := idE; + b := identityDispFut; + IF b THEN + b := ~t.SearchIns(e, n); + END; + IF b THEN + INC(nF); + END; ok := S.IdNextPubkey(FALSE, p, hash); END; END; END; - nF := t.NumberOfElems() - nA; RETURN t; END Find; @@ -295,12 +333,12 @@ MODULE Duniter0IdentitySearch; PROCEDURE FilterItem (VAR item: ARRAY OF CHAR); BEGIN (*FilterItem*) - IF item[0] = futureIcon THEN + IF (item[0] = oldIcon) OR (item[0] = futureIcon) THEN Strings.Replace(item, 0, 2, ''); END; END FilterItem; - PROCEDURE Certs (IN h: S.Hash; IN pubkey: B.Pubkey; member: BOOLEAN); + PROCEDURE Certs (IN h: S.Hash; IN pubkey: B.Pubkey; inBC: BOOLEAN); VAR @@ -319,7 +357,7 @@ MODULE Duniter0IdentitySearch; s: Dialog.String; BEGIN (*Certs*) - IF member THEN + IF inBC THEN okB := B.CertFrom(pubkey, posB); IF okB THEN sentCertsNb := posB.CertPosLen(); @@ -391,13 +429,13 @@ MODULE Duniter0IdentitySearch; END; identity.fields[9] := identity.fields[8]; - okB := member & B.CertTo(pubkey, posB); + okB := inBC & B.CertTo(pubkey, posB); IF okB THEN receivedCertsNb := posB.CertPosLen(); ELSE receivedCertsNb := 0; END; - IF member THEN + IF inBC THEN okS := B.IdPubComplete(pubkey, uid, m, toH, bnb, exp) & S.CertTo(toH, posS); ELSE okS := S.CertTo(h, posS); @@ -461,7 +499,7 @@ MODULE Duniter0IdentitySearch; identity.fields[7] := identity.fields[6]; END Certs; - PROCEDURE Get (IN hash: S.Hash; IN uid: ARRAY OF CHAR; OUT bloc, blocDate, pubkey, limitDate: ARRAY OF CHAR; OUT member: BOOLEAN); + PROCEDURE Get (IN hash: S.Hash; IN uid: ARRAY OF CHAR; OUT bloc, blocDate, pubkey, limitDate: ARRAY OF CHAR; OUT inBC, member: BOOLEAN); VAR @@ -474,8 +512,9 @@ MODULE Duniter0IdentitySearch; b, m: BOOLEAN; BEGIN (*Get*) - member := B.IdUidComplete(uid, p, m, h, bnb, exp); - IF member THEN + inBC := B.IdUidComplete(uid, p, m, h, bnb, exp); + member := inBC & m; + IF inBC THEN Strings.IntToString(bnb, bloc); b := B.TimeOf(bnb, mt, t); ASSERT(b); BA.TimestampToString(mt, d); @@ -569,28 +608,56 @@ MODULE Duniter0IdentitySearch; END; END FixCertNextDate; + PROCEDURE CalcQuality (OUT quality: ARRAY OF CHAR); + + VAR + + pubs: ARRAY 1 OF B.Pubkey; + + BEGIN (*CalcQuality*) + pubs[0] := identity.fields[2]$; + Strings.RealToStringForm(100 * B.PercentOfSentries(pubs), 16, 6, - 2, '', quality); + quality := quality + "%"; + END CalcQuality; + + PROCEDURE CalcCentrality (OUT centrality: ARRAY OF CHAR); + + BEGIN (*CalcCentrality*) + Strings.RealToStringForm(100 * C.CountOne(identity.fields[2]$), 16, 6, - 2, '', centrality); + centrality := centrality + "%"; + END CalcCentrality; + PROCEDURE Fix; VAR i: INTEGER; hash: B.Hash; + inBC: BOOLEAN; BEGIN (*Fix*) - ring.Change(identity.fields[0]); - hash := identityHash[identityList.index]; - identity.fields[10] := hash$; - Get(hash, identity.fields[0], identity.fields[16], identity.fields[18], identity.fields[2], identity.fields[4], identity.member); - identity.sentry := identity.member & B.IsSentry(identity.fields[2]$); - FixCertNextDate(identity.member, identity.fields[2]$, identity.fields[14]); - Certs(hash, identity.fields[2]$, identity.member); - IF identity.calcDist THEN - identity.distanceOK := NotTooFar(identity.member, identity.fields[12]); - END; - FOR i := 0 TO nonEditableNb - 1 DO - identity.fields[2 * i + 1] := identity.fields[2 * i]; - END; - Dialog.Update(identity); + IF identityList.len > 0 THEN + ring.Change(identity.fields[0]); + hash := identityHash[identityList.index]; + identity.fields[10] := hash$; + Get(hash, identity.fields[0], identity.fields[16], identity.fields[18], identity.fields[2], identity.fields[4], inBC, identity.member); + identity.sentry := identity.member & B.IsSentry(identity.fields[2]$); + FixCertNextDate(identity.member, identity.fields[2]$, identity.fields[14]); + Certs(hash, identity.fields[2]$, inBC); + IF identity.calcDist THEN + identity.distanceOK := NotTooFar(identity.member, identity.fields[12]); + END; + IF identity.calcQual THEN + CalcQuality(identity.fields[20]); + END; + IF identity.calcCentr THEN + CalcCentrality(identity.fields[22]); + END; + FOR i := 0 TO nonEditableNb - 1 DO + identity.fields[2 * i + 1] := identity.fields[2 * i]; + END; + Dialog.Update(identity); + END; END Fix; PROCEDURE DoSearch; @@ -604,14 +671,15 @@ MODULE Duniter0IdentitySearch; BEGIN (*DoSearch*) IF ring.BackEmpty() THEN A.New(t); - identityNb := 0; identityFutNb := 0; + identityOldNb := 0; identityNb := 0; identityFutNb := 0; ELSE UpdateCombo(hint, maxItems); - t := Find(hint.item, identityNb, identityFutNb); + t := Find(hint.item, identityOldNb, identityNb, identityFutNb); END; + Dialog.UpdateInt(identityOldNb); Dialog.UpdateInt(identityNb); Dialog.UpdateInt(identityFutNb); - identityList.SetLen(identityNb + identityFutNb); + identityList.SetLen(t.NumberOfElems()); IF identityList.len = 0 THEN identityHash := NIL; ELSE @@ -624,8 +692,10 @@ MODULE Duniter0IdentitySearch; identityHash[i] := e.hash; IF e.future THEN identityList.SetItem(i, futureIcon + ' ' + e.uid$); - ELSE + ELSIF e.active THEN identityList.SetItem(i, e.uid$); + ELSE + identityList.SetItem(i, oldIcon + ' ' + e.uid$); END; END; INC(i); @@ -641,9 +711,12 @@ MODULE Duniter0IdentitySearch; sentCertsFutNb := 0; sentCerts.SetLen(0); identity.member := FALSE; + identity.sentry := FALSE; + identity.distanceOK := FALSE; FOR i := 0 TO 2 * nonEditableNb - 1 DO identity.fields[i] := ""; END; + Dialog.UpdateInt(identityOldNb); Dialog.UpdateInt(identityNb); Dialog.UpdateInt(identityFutNb); Dialog.UpdateInt(receivedCertsNb); @@ -728,6 +801,18 @@ MODULE Duniter0IdentitySearch; par.disabled := ~identity.calcDist; END DistanceGuard; + PROCEDURE QualityGuard* (VAR par: Dialog.Par); + + BEGIN (*QualityGuard*) + par.disabled := ~identity.calcQual; + END QualityGuard; + + PROCEDURE CentralityGuard* (VAR par: Dialog.Par); + + BEGIN (*CentralityGuard*) + par.disabled := ~identity.calcCentr; + END CentralityGuard; + PROCEDURE DistanceNotifier* (op, from, to: INTEGER); BEGIN (*DistanceNotifier*) @@ -736,6 +821,22 @@ MODULE Duniter0IdentitySearch; END; END DistanceNotifier; + PROCEDURE QualityNotifier* (op, from, to: INTEGER); + + BEGIN (*QualityNotifier*) + IF (op = Dialog.changed) & identity.calcQual THEN + Fix; + END; + END QualityNotifier; + + PROCEDURE CentralityNotifier* (op, from, to: INTEGER); + + BEGIN (*CentralityNotifier*) + IF (op = Dialog.changed) & identity.calcCentr THEN + Fix; + END; + END CentralityNotifier; + PROCEDURE CopyReceived*; BEGIN (*CopyReceived*) @@ -743,6 +844,7 @@ MODULE Duniter0IdentitySearch; receivedCerts.GetItem(receivedCerts.index, hint.item); FilterItem(hint.item); Dialog.UpdateList(hint); + Search; END; END CopyReceived; @@ -753,6 +855,7 @@ MODULE Duniter0IdentitySearch; sentCerts.GetItem(sentCerts.index, hint.item); FilterItem(hint.item); Dialog.UpdateList(hint); + Search; END; END CopySent; @@ -818,7 +921,16 @@ MODULE Duniter0IdentitySearch; END; END CertsNotifier; + PROCEDURE NbNotifier* (op, from, to: INTEGER); + + BEGIN (*NbNotifier*) + IF op = Dialog.changed THEN + DoSearch; + END; + END NbNotifier; + BEGIN (*Duniter0IdentitySearch*) - identity.calcDist := TRUE; + identity.calcDist := TRUE; identity.calcQual := FALSE; identity.calcCentr := FALSE; + identityDispOld := FALSE; identityDispMem := TRUE; identityDispFut := TRUE; InitRing(ring); END Duniter0IdentitySearch. diff --git a/Standalone version/Sources/Duniter0/Members.txt b/Standalone version/Sources/Duniter0/Members.txt index d6cf3ec..bef5d9e 100644 --- a/Standalone version/Sources/Duniter0/Members.txt +++ b/Standalone version/Sources/Duniter0/Members.txt @@ -16,6 +16,10 @@ MODULE Duniter0Members; IMPORT + (* + L := StdLog, + *) + B := Duniter0Blockchain; PROCEDURE Count* (OUT counts: POINTER TO ARRAY OF INTEGER); @@ -67,4 +71,55 @@ MODULE Duniter0Members; END; END Count; + PROCEDURE CountP* (period: INTEGER; OUT counts: POINTER TO ARRAY OF INTEGER); + + CONST + + day = 60 * 60 * 24; + + VAR + + ok, ok2, b: BOOLEAN; + pk: B.Pubkey; + uid: B.String; + jb, lb, nb, n, list: INTEGER; + mT, time, t0: LONGINT; + p: INTEGER; + + BEGIN (*CountP*) + p := period * day; + t0 := MAX(LONGINT); + ok := B.JLNextPubkey(TRUE, pk); + WHILE ok DO + ok2 := B.JLPub(pk, list) & B.JLPubLNext(list, jb, lb); + WHILE ok2 DO + b := B.TimeOf(jb, mT, time); ASSERT(b); + t0 := MIN(t0, time); + ok2 := B.JLPubLNext(list, jb, lb); + END; + ok := B.JLNextPubkey(FALSE, pk); + END; + NEW(counts, SHORT((B.RealNow() - t0 + p - 1) DIV p)); + FOR n := 0 TO LEN(counts) - 1 DO + counts[n] := 0; + END; + ok := B.JLNextPubkey(TRUE, pk); + WHILE ok DO + ok2 := B.JLPub(pk, list) & B.JLPubLNext(list, jb, lb); + WHILE ok2 DO + b := B.TimeOf(jb, mT, time); ASSERT(b); + INC(counts[SHORT((time - t0) DIV p)]); + IF lb # B.hasNotLeaved THEN + b := B.TimeOf(lb, mT, time); ASSERT(b); + DEC(counts[SHORT((time - t0) DIV p)]); + END; + ok2 := B.JLPubLNext(list, jb, lb); + END; + ok := B.JLNextPubkey(FALSE, pk); + END; + FOR n := 1 TO LEN(counts) - 1 DO + INC(counts[n], counts[n - 1]); + END; + END CountP; + END Duniter0Members. diff --git a/Standalone version/Sources/Duniter0/MembersPrint.txt b/Standalone version/Sources/Duniter0/MembersPrint.txt index d32610c..4e968d5 100644 --- a/Standalone version/Sources/Duniter0/MembersPrint.txt +++ b/Standalone version/Sources/Duniter0/MembersPrint.txt @@ -41,7 +41,33 @@ MODULE Duniter0MembersPrint; END; Views.OpenView(TextViews.dir.New(t)); END Do; + + PROCEDURE DoP* (period: INTEGER); + + + VAR + + t: TextModels.Model; + f: TextMappers.Formatter; + a: POINTER TO ARRAY OF INTEGER; + i: INTEGER; + + BEGIN (*DoP*) + M.CountP(period, a); + t := TextModels.dir.New(); + f.ConnectTo(t); + FOR i := 0 TO LEN(a) - 1 DO + f.WriteTab; + f.WriteInt(i * period); + f.WriteTab; + f.WriteInt(a[i]); + f.WriteLn; + END; + Views.OpenView(TextViews.dir.New(t)); + END DoP; END Duniter0MembersPrint. -Duniter0MembersPrint.Do; \ No newline at end of file +Duniter0MembersPrint.Do; + +"Duniter0MembersPrint.DoP(20)" diff --git a/Standalone version/Sources/Duniter0/QualitiesJson.txt b/Standalone version/Sources/Duniter0/QualitiesJson.txt new file mode 100644 index 0000000..c5a329f --- /dev/null +++ b/Standalone version/Sources/Duniter0/QualitiesJson.txt @@ -0,0 +1,61 @@ +(* +Duniter0: WotWizard. + +Copyright (C) 2017 GérardMeunier + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +MODULE Duniter0QualitiesJson; + + + + IMPORT + + Q := Duniter0QualitiesSetsArr, + + B := Duniter0Blockchain, J := UtilJson, TextMappers, TextModels, TextViews, Views; + + PROCEDURE Print*; + + VAR + + props, propsId: Q.Props; + i: INTEGER; + t: TextModels.Model; + f: TextMappers.Formatter; + + BEGIN (*Print*) + Q.Count(props, propsId); + J.StartObject; + J.PushString("Qualities"); + J.BuildField("description"); + J.PushInteger(B.LastBlock()); + J.BuildField("block"); + J.StartArray; + FOR i := 0 TO LEN(propsId) - 1 DO + J.StartObject; + J.PushString(propsId[i].id); + J.BuildField("id"); + J.PushReal(propsId[i].prop); + J.BuildField("quality"); + J.BuildObject; + END; + J.BuildArray; + J.BuildField("values"); + J.BuildObject; + t := TextModels.dir.New(); + f.ConnectTo(t); + J.GetJson().Write(f); + Views.OpenView(TextViews.dir.New(t)); + END Print; + + END Duniter0QualitiesJson. + +DevDebug.UnloadThis Duniter0QualitiesPrint Duniter0QualitiesJson Duniter0QualitiesSetsArr Duniter0QualitiesSetsAVL Duniter0QualitiesAVL + +Duniter0QualitiesJson.Print; diff --git a/Standalone version/Sources/Duniter0/QualitiesSetsArr.txt b/Standalone version/Sources/Duniter0/QualitiesSetsArr.txt new file mode 100644 index 0000000..768c8fe --- /dev/null +++ b/Standalone version/Sources/Duniter0/QualitiesSetsArr.txt @@ -0,0 +1,211 @@ +(* +Duniter0: WotWizard. + +Copyright (C) 2017 GérardMeunier + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +MODULE Duniter0QualitiesSetsArr; + + + + (* Calculate qualities with UtilSets; numbering of members is done by array; fast *) + + IMPORT + + A := UtilAvlTree, BA := Duniter0Basic, B := Duniter0Blockchain, UtilSort, S := UtilSets; + + TYPE + + Members = POINTER TO ARRAY OF B.Pubkey; + + MembersFind = RECORD (UtilSort.T) + len: INTEGER; + m: Members; + END; + + Links = POINTER TO ARRAY OF S.Set; + + PropOfSentries* = POINTER TO RECORD + id-: B.String; + prop-: REAL; + END; + + Props* = POINTER TO ARRAY OF PropOfSentries; + + PropsSort = EXTENSIBLE RECORD (UtilSort.T) + t: Props; + END; + + PropsSortId = EXTENSIBLE RECORD (PropsSort) + END; + + VAR + + members: MembersFind; + links: Links; + sentries: S.Set; + + PROCEDURE (VAR m: MembersFind) Less (i, j: INTEGER): BOOLEAN; + + BEGIN (*Less*) + RETURN m.m[i] < m.m[j]; + END Less; + + PROCEDURE (VAR s: PropsSort) Swap (i, j: INTEGER); + + VAR + + p: PropOfSentries; + + BEGIN (*Swap*) + p := s.t[i]; s.t[i] := s.t[j]; s.t[j] := p; + END Swap; + + PROCEDURE (VAR s: PropsSort) Less (p1, p2: INTEGER): BOOLEAN, EXTENSIBLE; + + BEGIN (*Less*) + RETURN (s.t[p1].prop > s.t[p2].prop) OR (s.t[p1].prop = s.t[p2].prop) & (BA.CompP(s.t[p1].id, s.t[p2].id) = A.lt); + END Less; + + PROCEDURE (VAR s: PropsSortId) Less (p1, p2: INTEGER): BOOLEAN; + + BEGIN (*Less*) + RETURN BA.CompP(s.t[p1].id, s.t[p2].id) = A.lt; + END Less; + + PROCEDURE Find (p: B.Pubkey; OUT n: INTEGER): BOOLEAN; + + BEGIN (*Find*) + n := members.len; + members.m[n] := p; + members.BinSearch(0, n - 1, n); + IF n = members.len THEN + RETURN FALSE; + END; + RETURN TRUE; + END Find; + + PROCEDURE Update; + + VAR + + ok: BOOLEAN; + p, to: B.Pubkey; + i, e: INTEGER; + pos: B.CertPos; + + BEGIN (*Update*) + members.len := B.IdLen(); + NEW(members.m, members.len + 1); + sentries := S.NewSet(); + i := 0; + ok := B.IdNextPubkey(TRUE, p); + WHILE ok DO + ASSERT((i = 0) OR (p > members.m[i - 1])); + members.m[i] := p; + IF B.IsSentry(p) THEN + sentries.Incl(i); + END; + INC(i); + ok := B.IdNextPubkey(FALSE, p); + END; + ASSERT(i = members.len); + + NEW(links, members.len); + FOR i := 0 TO members.len - 1 DO + links[i] := S.NewSet(); + END; + FOR i := 0 TO members.len - 1 DO + ok := B.CertTo(members.m[i], pos) & pos.CertNextPos(p, to); + WHILE ok DO + IF Find(p, e) THEN + links[i].Incl(e); + END; + ok := pos.CertNextPos(p, to); + END; + END; + END Update; + + PROCEDURE PercentOfSentries (IN pubkey: B.Pubkey): REAL; + + VAR + + set, frontier, newFrontier: S.Set; + frontierI: S.SetIterator; + e, i: INTEGER; + ok: BOOLEAN; + + BEGIN (*PercentOfSentries*) + IF ~Find(pubkey, e) THEN + RETURN 0.; + END; + set := S.NewSet(); + set.Incl(e); + frontier := S.NewSet(); + frontier.Incl(e); + FOR i := 1 TO B.pars.stepMax - 1 DO + newFrontier := S.NewSet(); + frontierI.Attach(frontier); + ok := frontierI.FirstE(e); + WHILE ok DO + newFrontier := newFrontier.Union(links[e]); + ok := frontierI.NextE(e); + END; + frontier := newFrontier; + set := set.Union(frontier); + END; + RETURN set.Inter(sentries).nbElems / sentries.nbElems; + END PercentOfSentries; + + PROCEDURE Count* (OUT props, propsId: Props); + + VAR + + ok, b: BOOLEAN; + p: B.Pubkey; + i, n: INTEGER; + c: PropOfSentries; + s: PropsSort; + sId: PropsSortId; + + BEGIN (*Count*) + n := B.IdLenM(); + NEW(props, n); + i := 0; + ok := B.IdNextPubkeyM(TRUE, p); + WHILE ok DO + NEW(c); + b := B.IdPub(p, c.id); ASSERT(b); + c.prop := PercentOfSentries(p); + props[i] := c; + INC(i); + ok := B.IdNextPubkeyM(FALSE, p); + END; + s.t := props; + s.QuickSort(0, n - 1); + NEW(propsId, n); + FOR i := 0 TO n - 1 DO + propsId[i] := props[i]; + END; + sId.t := propsId; + sId.QuickSort(0, n - 1); + END Count; + + PROCEDURE CountOne* (p: B.Pubkey): REAL; + + BEGIN (*CountOne*) + RETURN PercentOfSentries(p); + END CountOne; + + BEGIN (*Duniter0QualitiesSetsArr*) + B.AddUpdateProc(Update); + B.UpdateAll; + CLOSE + B.RemoveUpdateProc(Update); + END Duniter0QualitiesSetsArr. diff --git a/Standalone version/Sources/Duniter0/Sandbox.txt b/Standalone version/Sources/Duniter0/Sandbox.txt index fc71791..2b80af9 100644 --- a/Standalone version/Sources/Duniter0/Sandbox.txt +++ b/Standalone version/Sources/Duniter0/Sandbox.txt @@ -544,13 +544,13 @@ MODULE Duniter0Sandbox; VAR t, tt: S.Table; - i, n, bnb: INTEGER; + i, n: INTEGER; cur: CurId; id: Identity; hE: IdHashE; e: A.Elem; b: BOOLEAN; - now, exp: LONGINT; + now: LONGINT; hash: Hash; r: S.Row; pub: Pubkey; @@ -724,29 +724,16 @@ MODULE Duniter0Sandbox; Certifications(d); END Scan; - PROCEDURE IsFree (IN p: Pubkey): BOOLEAN; - - VAR - - pos: CertPos; - - BEGIN (*IsFree*) - RETURN ~CertFrom(p, pos); - END IsFree; - PROCEDURE Init; BEGIN (*Init*) - B.AddUpdateProc(Scan, TRUE); - B.AddUpdateProc(Scan, FALSE); - B.FixIsFree(IsFree); - B.Update; + B.AddUpdateProc(Scan); + B.UpdateAll; Scan; END Init; BEGIN (*Duniter0Sandbox*) Init; CLOSE - B.RemoveUpdateProc(Scan, TRUE); - B.RemoveUpdateProc(Scan, FALSE); + B.RemoveUpdateProc(Scan); END Duniter0Sandbox. diff --git a/Standalone version/Sources/Duniter0/WWViews.txt b/Standalone version/Sources/Duniter0/WWViews.txt index 670cc97..3ab694a 100644 --- a/Standalone version/Sources/Duniter0/WWViews.txt +++ b/Standalone version/Sources/Duniter0/WWViews.txt @@ -1,5 +1,5 @@ (* -Duniter: WotWizard. +Duniter0: WotWizard. Copyright (C) 2017 GérardMeunier @@ -22,21 +22,18 @@ MODULE Duniter0WWViews; StdLog, *) - A := UtilAvlTree, B := Duniter0Blockchain, BA := Duniter0Basic, Containers, Controllers, Controls, Converters, DevSearch, Dialog, Documents, Files, Fonts, J := UtilJson, Math, Models, Ports, Properties, Sequencers, Services, StdCmds, Stores, Strings, TextMappers, TextModels, TextRulers, TextViews, Views, W := Duniter0WotWizard, WP := Duniter0WotWizardPrint, Windows; + A := UtilAvlTree, B := Duniter0Blockchain, BA := Duniter0Basic, Containers, Controllers, Controls, Converters, DevSearch, Dialog, Documents, Files, Fonts, J := UtilJson, Math, Models, Ports, Properties, Sequencers, Services, StdCmds, Stores, Strings, TextMappers, TextModels, TextRulers, TextViews, Views, W := Duniter0WotWizard, Windows; CONST - maxStackLengthDir = "Duniter0/Rsrc"; - maxStackLengthName = "WW_Max_Stack.odc"; - - rsrcDir = "Duniter/Rsrc"; (* Resources directory *) + parametersDir = "Duniter0/Rsrc"; + parametersName = "Parameters.odc"; textMeta = "WWMeta.json"; (* File containing metadata *) textByDate = "WWByDate.json"; (* File containing entries data, sorted by dates *) - textByName = "WWByName.json"; (* File containing entries data, sorted by names *) - oldEntriesName = "WW_Old_Entries.odc"; (* File containing previous metadata output *) - oldMetaName = "WW_Old_Meta.odc"; (* File containing previous entries data output *) + oldEntriesName = "WW_Old_Entries.json"; (* File containing previous metadata output *) + oldMetaName = "WW_Old_Meta.json"; (* File containing previous entries data output *) title = "WotWizard"; (* Title of the outputs *) @@ -86,8 +83,8 @@ MODULE Duniter0WWViews; showOldEntries-: BOOLEAN; - maxStackLength*, - oldMaxStackLength: LONGINT; + maxSize*, + oldMaxSize: LONGINT; (* Find the first View *) PROCEDURE FindFirst (): View; @@ -142,7 +139,7 @@ MODULE Duniter0WWViews; BEGIN (*Equal*) WITH e1: W.PropDate DO WITH e2: W.PropDate DO - RETURN (e1.id$ = e2.id$) & (e1.date = e2.date) & (e1.after = e2.after) & (e1.proba = e2.proba); + RETURN (e1.id$ = e2.id$) & (e1.date = e2.date) & (e1.after = e2.after) & (Math.Round(1.E16 * e1.proba) = Math.Round(1.E16 * e2.proba)); END; END; END Equal; @@ -205,7 +202,7 @@ MODULE Duniter0WWViews; f.WriteString(e.id); f.WriteTab; f.WriteString(": "); f.WriteMsg("#Duniter0:Proba"); f.WriteString(" = "); - f.WriteIntForm(ENTIER(Math.Round(e.proba * 100)), 10, 3, " ", FALSE); (* Digit space *) + f.WriteIntForm(ENTIER(Math.Round(e.proba * 100)), 10, 3, "", FALSE); (* Digit space *) f.WriteString("%"); f.WriteLn; END; @@ -262,7 +259,7 @@ MODULE Duniter0WWViews; END; f.WriteTab; f.WriteString(": "); f.WriteMsg("#Duniter0:Proba"); f.WriteString(" = "); - f.WriteIntForm(ENTIER(Math.Round(e.proba * 100)), 10, 3, " ", FALSE); (* Digit space *) + f.WriteIntForm(ENTIER(Math.Round(e.proba * 100)), 10, 3, "", FALSE); (* Digit space *) f.WriteString("%"); f.WriteLn; END; @@ -439,75 +436,8 @@ MODULE Duniter0WWViews; SetNotDirty(v); END WriteText; - (* When the WotWizard lists have been modified, stores on disk the old results versions in oldEntriesName and oldMetaName files *) - PROCEDURE OldResults (occurD: A.Tree; meta: J.Json); - - VAR - - t: TextModels.Model; - f: TextMappers.Formatter; - v: Views.View; - loc: Files.Locator; - - PROCEDURE Header (VAR f: TextMappers.Formatter); - - VAR - - r: TextRulers.Ruler; - prop: Controls.Prop; - c: Controls.Control; - s: Dialog.String; - w, h: INTEGER; - - BEGIN (*Header*) - r := TextRulers.dir.New(NIL); - TextRulers.SetCentered(r); - TextRulers.SetFixedRight(r, width); - f.WriteView(r); - f.rider.SetAttr(TextModels.NewWeight(f.rider.attr, Fonts.normal)); - f.rider.SetAttr(TextModels.NewSize(f.rider.attr, titleSize)); - f.WriteMsg(title); - f.WriteLn; - f.rider.SetAttr(TextModels.NewSize(f.rider.attr, headSize)); - f.WriteMsg("#Duniter0:PreviousDisplay"); - f.WriteLn; - f.WriteLn; - r := TextRulers.dir.New(NIL); - TextRulers.AddTab(r, thirdCtrlPos); - TextRulers.MakeCenterTab(r); - f.WriteView(r); - f.WriteTab; - InitProp(prop); - prop.link := "DevSearch.Compare"; - prop.label := "#Duniter0:Compare"; - Dialog.MapString(prop.label, s); - c := Controls.dir.NewPushButton(prop); - f.WriteView(c); - c.context.GetSize(w, h); - c.context.SetSize(c.font.StringWidth(s) + buttonOffset, h); - f.WriteLn; - END Header; - - BEGIN (*OldResults*) - loc := Files.dir.This(""); ASSERT(loc.res = 0, 100); - - t := TextModels.dir.New(); - f.ConnectTo(t); - Header(f); - ByDates(f, occurD); - v := TextViews.dir.New(t); - Views.RegisterView(v, loc, oldEntriesName); - - t := TextModels.dir.New(); - f.ConnectTo(t); - Header(f); - Meta(f, meta); - v := TextViews.dir.New(t); - Views.RegisterView(v, loc, oldMetaName); - END OldResults; - (* Write the metadata duration, f, cNb & dNb with the help of fo, in json format; duration is the computation duration, f is the DuniterWotWizard.File structure, cNb and dNb are respectively the numbers of internal certifications and of external dossiers *) - PROCEDURE BuildMeta (duration: LONGINT; f: W.File; cNb, dNb: INTEGER): J.Json; + PROCEDURE BuildMeta (duration: LONGINT; f: W.File; permutations, cNb, dNb: INTEGER): J.Json; VAR @@ -563,6 +493,8 @@ MODULE Duniter0WWViews; J.StartObject; J.PushString(d.id); J.BuildField("newcomer"); + J.PushInteger(d.princCertif); + J.BuildField("main_certifs"); Strings.RealToStringForm(100 * d.proportionOfSentries, 16, 1, - 2, " ", s); J.PushString(s); J.BuildField("percent_of_sentries"); @@ -608,6 +540,8 @@ MODULE Duniter0WWViews; BA.TimestampToString(B.Now(), s); J.PushString(s); J.BuildField("now"); + J.PushInteger(permutations); + J.BuildField("permutations"); BA.TimeToString(duration, ss); J.PushString(ss); J.BuildField("computation_duration"); @@ -621,44 +555,79 @@ MODULE Duniter0WWViews; RETURN J.GetJson(); END BuildMeta; - (* Test whether the WotWizard lists have changed *) - PROCEDURE (v: View) UpdateText, NEW; + PROCEDURE BuildOccurDN (j: J.Json; OUT now: BA.DateTime; OUT oD, oN: A.Tree); VAR - f: W.File; - cNb, dNb: INTEGER; - ti, duration: LONGINT; - occurD, occurN: A.Tree; - meta: J.Json; - b, oM: BOOLEAN; - nowS: BA.DateTime; + f1, f2, f3: J.Fields; + d, n: J.Values; + i, k, m: INTEGER; + pD: W.PropDate; + pN: W.PropName; + e: A.Elem; + b: BOOLEAN; - BEGIN (*UpdateText*) - ti := Services.Ticks(); - IF ~W.BuildEntries(f, cNb, dNb, occurD, occurN) THEN - A.New(occurD); A.New(occurN); - END; - duration := Services.Ticks() - ti; - meta := BuildMeta(duration, f, cNb, dNb); - BA.TimestampToString(B.Now(), nowS); - oM := v.modified; - b := ~OccursEqual(occurD, v.occurD); - v.modified := v.modified OR b; - IF b & ~oM THEN - OldResults(v.occurD, v.meta); + BEGIN (*BuildOccurDN*) + A.New(oD); A.New(oN); + IF j = NIL THEN + now := ""; + ELSE + WITH j: J.Object DO + f1 := j.fields; + ASSERT(f1[0].name$ = "now", 100); + ASSERT(f1[0].value IS J.String, 101); + now := f1[0].value(J.String).s$; + ASSERT(f1[1].name$ = "dates", 102); + ASSERT(f1[1].value IS J.JsonVal, 103); + ASSERT(f1[1].value(J.JsonVal).json IS J.Array, 104); + d := f1[1].value(J.JsonVal).json(J.Array).elements; + IF d # NIL THEN + FOR i := 0 TO LEN(d) - 1 DO + ASSERT(d[i] IS J.JsonVal, 105); + ASSERT(d[i](J.JsonVal).json IS J.Object, 106); + f2 := d[i](J.JsonVal).json(J.Object).fields; + ASSERT(f2[0].name$ = "after", 107); + ASSERT(f2[0].value IS J.Bool, 108); + ASSERT(f2[1].name$ = "date", 109); + ASSERT(f2[1].value IS J.String, 110); + ASSERT(f2[2].name$ = "names", 111); + ASSERT(f2[2].value IS J.JsonVal, 112); + ASSERT(f2[2].value(J.JsonVal).json IS J.Array, 113); + n := f2[2].value(J.JsonVal).json(J.Array).elements; + FOR k := 0 TO LEN(n) - 1 DO + ASSERT(n[k] IS J.JsonVal, 114); + ASSERT(n[k](J.JsonVal).json IS J.Object, 115); + f3 := n[k](J.JsonVal).json(J.Object).fields; + ASSERT(f3[0].name$ = "name", 116); + ASSERT(f3[0].value IS J.String, 117); + ASSERT(f3[1].name$ = "proba", 118); + ASSERT(f3[1].value IS J.Real, 119); + NEW(pD); + pD.after := f2[0].value(J.Bool).bool; + pD.date := BA.StringToTimestamp(f2[1].value(J.String).s$); + pD.id := f3[0].value(J.String).s; + pD.proba := f3[1].value(J.Real).r; + e := pD; + b := oD.SearchIns(e, m); ASSERT(~b, 120); + NEW(pN); + pN.after := pD.after; + pN.date := pD.date; + pN.id := pD.id; + pN.proba := pD.proba; + e := pN; + b := oN.SearchIns(e, m); ASSERT(~b, 121); + END; + END; + END; + END; END; - v.nowS := nowS; v.occurD := occurD; v.occurN := occurN; v.meta := meta; - END UpdateText; + END BuildOccurDN; (* Save the WotWizard lists on disk, in files textByName and textByDate, whenever they have changed *) PROCEDURE (v: View) StoreText, NEW; CONST - textByName = "WWByName"; - textByDate = "WWByDate"; - textExt = "txt"; textConv = "CpcUtf8Conv.ExportUtf8"; VAR @@ -671,42 +640,136 @@ MODULE Duniter0WWViews; f: TextMappers.Formatter; nowS: BA.DateTime; + (* Print the entries sorted by dates in json format *) + PROCEDURE ByDates (occur: A.Tree); + + VAR + + e: A.Elem; + date: LONGINT; + after: BOOLEAN; + s: BA.DateTime; + ss: Dialog.String; + + BEGIN (*ByDates*) + date := - 1; + e := occur.Next(NIL); + WHILE e # NIL DO + WITH e: W.PropDate DO + IF (e.date # date) OR (e.after # after) THEN + IF date >= 0 THEN + J.BuildArray; + J.BuildField("names"); + J.BuildObject; + END; + date := e.date; after := e.after; + J.StartObject; + J.PushBoolean(e.after); + J.BuildField("after"); + IF e.date = BA.never THEN + Dialog.MapString("#Duniter:Never", ss); + J.PushString(ss); + ELSE + BA.TimestampToString(e.date, s); + J.PushString(s); + END; + J.BuildField("date"); + J.StartArray; + END; + J.StartObject; + J.PushString(e.id); + J.BuildField("name"); + J.PushReal(e.proba); + J.BuildField("proba"); + J.BuildObject; + END; + e := occur.Next(e); + END; + IF date >= 0 THEN + J.BuildArray; + J.BuildField("names"); + J.BuildObject; + END; + END ByDates; + BEGIN (*StoreText*) IF v.modified THEN - loc := Files.dir.This(""); ASSERT(loc.res = 0); + loc := Files.dir.This(""); ASSERT(loc.res = 0, 100); conv := Converters.list; WHILE (conv # NIL) & (conv.exp # textConv) DO conv := conv.next; END; - ASSERT(conv # NIL); + ASSERT(conv # NIL, 101); BA.TimestampToString(B.Now(), nowS); + IF v.meta # NIL THEN + t := TextModels.dir.New(); + f.ConnectTo(t); + v.meta.Write(f); + name := textMeta; + Views.Register(TextViews.dir.New(t), Views.dontAsk, loc, name, conv, res); ASSERT(res = 0, 102); + END; t := TextModels.dir.New(); f.ConnectTo(t); - f.WriteString(" "); - f.WriteString(nowS); - f.WriteString(" (UTC+0)"); - f.WriteLn; - WP.ByDates(f, v.occurD); - name := textByDate + '.' + textExt; - Views.Register(TextViews.dir.New(t), Views.dontAsk, loc, name, conv, res); ASSERT(res = 0); - t := TextModels.dir.New(); - f.ConnectTo(t); - f.WriteString(" "); - f.WriteString(nowS); - f.WriteString(" (UTC+0)"); - f.WriteLn; - WP.ByNames(f, v.occurN); - name := textByName + '.' + textExt; - Views.Register(TextViews.dir.New(t), Views.dontAsk, loc, name, conv, res); ASSERT(res = 0); + J.StartObject; + J.PushString(nowS); + J.BuildField("now"); + J.StartArray; + ByDates(v.occurD); + J.BuildArray; + J.BuildField("dates"); + J.BuildObject; + J.GetJson().Write(f); + name := textByDate; + Views.Register(TextViews.dir.New(t), Views.dontAsk, loc, name, conv, res); ASSERT(res = 0, 103); END; END StoreText; + (* Test whether the WotWizard lists have changed *) + PROCEDURE (v: View) UpdateText, NEW; + + VAR + + f: W.File; + cNb, dNb, permutations: INTEGER; + ti, duration: LONGINT; + occurD, occurN: A.Tree; + meta: J.Json; + b, oM: BOOLEAN; + nowS: BA.DateTime; + loc: Files.Locator; + + BEGIN (*UpdateText*) + ti := Services.Ticks(); + IF ~W.BuildEntries(f, permutations, cNb, dNb, occurD, occurN) THEN + A.New(occurD); A.New(occurN); + END; + duration := Services.Ticks() - ti; + meta := BuildMeta(duration, f, permutations, cNb, dNb); + BA.TimestampToString(B.Now(), nowS); + oM := v.modified; + b := ~OccursEqual(occurD, v.occurD); + v.modified := v.modified OR b; + IF b & ~oM THEN + loc := Files.dir.This(""); ASSERT(loc.res = 0, 100); + Files.dir.Delete(loc, oldEntriesName); + Files.dir.Rename(loc, textByDate, oldEntriesName, Files.dontAsk); + Files.dir.Delete(loc, oldMetaName); + Files.dir.Rename(loc, textMeta, oldMetaName, Files.dontAsk); + END; + v.nowS := nowS; v.occurD := occurD; v.occurN := occurN; v.meta := meta; + IF v.modified THEN + v.StoreText; + END; + END UpdateText; + PROCEDURE (v: View) InstallText, NEW; BEGIN (*InstallText*) v.text := TextViews.dir.New(TextModels.dir.New()); Stores.Join(v, v.text); v.text.ThisController().SetOpts({Containers.noCaret}); + BuildOccurDN(J.Read("", textByDate), v.nowS, v.occurD, v.occurN); + v.meta := J.Read("", textMeta); v.UpdateText; END InstallText; @@ -843,9 +906,52 @@ MODULE Duniter0WWViews; v: View; vv: TextViews.View; - vvo: Views.View; loc: Files.Locator; dN: INTEGER; + t: TextModels.Model; + f: TextMappers.Formatter; + j: J.Json; + nowS: BA.DateTime; + occurD, occurN: A.Tree; + + PROCEDURE Header (VAR f: TextMappers.Formatter); + + VAR + + r: TextRulers.Ruler; + prop: Controls.Prop; + c: Controls.Control; + s: Dialog.String; + w, h: INTEGER; + + BEGIN (*Header*) + r := TextRulers.dir.New(NIL); + TextRulers.SetCentered(r); + TextRulers.SetFixedRight(r, width); + f.WriteView(r); + f.rider.SetAttr(TextModels.NewWeight(f.rider.attr, Fonts.normal)); + f.rider.SetAttr(TextModels.NewSize(f.rider.attr, titleSize)); + f.WriteMsg(title); + f.WriteLn; + f.rider.SetAttr(TextModels.NewSize(f.rider.attr, headSize)); + f.WriteMsg("#Duniter:PreviousDisplay"); + f.WriteLn; + f.WriteLn; + r := TextRulers.dir.New(NIL); + TextRulers.AddTab(r, thirdCtrlPos); + TextRulers.MakeCenterTab(r); + f.WriteView(r); + f.WriteTab; + InitProp(prop); + prop.link := "DevSearch.Compare"; + prop.label := "#Duniter:Compare"; + Dialog.MapString(prop.label, s); + c := Controls.dir.NewPushButton(prop); + f.WriteView(c); + c.context.GetSize(w, h); + c.context.SetSize(c.font.StringWidth(s) + buttonOffset, h); + f.WriteLn; + END Header; BEGIN (*Clear*) v := FindFirst(); @@ -855,8 +961,8 @@ MODULE Duniter0WWViews; IF showOldEntries THEN loc := Files.dir.This(""); ASSERT(loc.res = 0, 100); - vvo := Views.OldView(loc, oldMetaName); - IF vvo # NIL THEN + j := J.Read("", oldMetaName); + IF j # NIL THEN IF dateNameMeta # meta THEN dN := dateNameMeta; dateNameMeta := meta; @@ -870,12 +976,16 @@ MODULE Duniter0WWViews; Views.OpenView(vv); StdCmds.SetEditMode; SetNotDirty(vv); - Views.OpenView(vvo); + t := TextModels.dir.New(); + f.ConnectTo(t); + Header(f); + Meta(f, j); + Views.OpenView(TextViews.dir.New(t)); DevSearch.Compare; END; - vvo := Views.OldView(loc, oldEntriesName); - IF vvo # NIL THEN + j := J.Read("", oldEntriesName); + IF j # NIL THEN IF dateNameMeta # byDate THEN dN := dateNameMeta; dateNameMeta := byDate; @@ -889,7 +999,12 @@ MODULE Duniter0WWViews; Views.OpenView(vv); StdCmds.SetEditMode; SetNotDirty(vv); - Views.OpenView(vvo); + t := TextModels.dir.New(); + f.ConnectTo(t); + Header(f); + BuildOccurDN(j, nowS, occurD, occurN); + ByDates(f, occurD); + Views.OpenView(TextViews.dir.New(t)); DevSearch.Compare; END; @@ -932,7 +1047,7 @@ MODULE Duniter0WWViews; showOldEntries := FALSE; END HideOldEntries; - PROCEDURE StoreMaxStackLength; + PROCEDURE StoreParameters; VAR @@ -941,29 +1056,29 @@ MODULE Duniter0WWViews; wr: Stores.Writer; res: INTEGER; - BEGIN (*StoreMaxStackLength*) - l := Files.dir.This(maxStackLengthDir); ASSERT(l.res = 0); - f := Files.dir.New(l, Files.dontAsk); ASSERT(f # NIL); + BEGIN (*StoreParameters*) + l := Files.dir.This(parametersDir); ASSERT(l.res = 0, 100); + f := Files.dir.New(l, Files.dontAsk); ASSERT(f # NIL, 101); wr.ConnectTo(f); - wr.WriteLong(maxStackLength); - f.Register(maxStackLengthName, '', Files.dontAsk, res); ASSERT(res = 0); - END StoreMaxStackLength; + wr.WriteLong(maxSize); + f.Register(parametersName, '', Files.dontAsk, res); ASSERT(res = 0, 102); + END StoreParameters; - PROCEDURE MaxStackLengthOK*; + PROCEDURE ParametersOK*; - BEGIN (*MaxStackLengthOK*) - IF maxStackLength # oldMaxStackLength THEN - oldMaxStackLength := maxStackLength; - W.ChangeMaxStackLength(maxStackLength); - StoreMaxStackLength; + BEGIN (*ParametersOK*) + IF maxSize # oldMaxSize THEN + oldMaxSize := maxSize; + W.ChangeParameters(maxSize); + StoreParameters; END; - END MaxStackLengthOK; + END ParametersOK; - PROCEDURE MaxStackLengthOKGuard* (VAR par: Dialog.Par); + PROCEDURE ParametersOKGuard* (VAR par: Dialog.Par); - BEGIN (*MaxStackLengthOKGuard*) - par.disabled := maxStackLength = oldMaxStackLength; - END MaxStackLengthOKGuard; + BEGIN (*ParametersOKGuard*) + par.disabled := maxSize = oldMaxSize; + END ParametersOKGuard; PROCEDURE New* (): Views.View; @@ -974,8 +1089,8 @@ MODULE Duniter0WWViews; BEGIN (*New*) NEW(v); A.New(v.occurD); - v.InstallText; v.modified := FALSE; + v.InstallText; v.WriteText; RETURN v; END New; @@ -1003,24 +1118,24 @@ MODULE Duniter0WWViews; BEGIN (*Init*) dateNameMeta := byName; showOldEntries := FALSE; - l := Files.dir.This(maxStackLengthDir); - f := Files.dir.Old(l, maxStackLengthName, Files.shared); + l := Files.dir.This(parametersDir); + f := Files.dir.Old(l, parametersName, Files.shared); IF f = NIL THEN - maxStackLength := W.maxStackLength; - StoreMaxStackLength; + maxSize := W.maxSize; + StoreParameters; ELSE rd.ConnectTo(f); - rd.ReadLong(maxStackLength); - W.ChangeMaxStackLength(maxStackLength); + rd.ReadLong(maxSize); + W.ChangeParameters(maxSize); END; - oldMaxStackLength := maxStackLength; - B.AddUpdateProc(Update, FALSE); + oldMaxSize := maxSize; + B.AddUpdateProc(Update); END Init; BEGIN (*Duniter0WWViews*) Init; CLOSE - B.RemoveUpdateProc(Update, FALSE); + B.RemoveUpdateProc(Update); END Duniter0WWViews. "Duniter0WWViews.Deposit;StdCmds.Open" diff --git a/Standalone version/Sources/Duniter0/WotWizard.txt b/Standalone version/Sources/Duniter0/WotWizard.txt index 253e53c..f782d44 100644 --- a/Standalone version/Sources/Duniter0/WotWizard.txt +++ b/Standalone version/Sources/Duniter0/WotWizard.txt @@ -23,14 +23,12 @@ MODULE Duniter0WotWizard; Lg := StdLog, *) - A := UtilAvlTree, B := Duniter0Blockchain, S := Duniter0Sandbox, BA := Duniter0Basic, Services; + A := UtilAvlTree, B := Duniter0Blockchain, S := Duniter0Sandbox, BA := Duniter0Basic; CONST maxSizeDef = 430000000; (* Default value for the greatest allowed allocated memory size *) - (* Default value for the greatest allowed run time for CalcPermutations *) - (* Sizes of different types *) INS = SIZE(INTEGER); LIS = SIZE(LONGINT); @@ -867,7 +865,7 @@ MODULE Duniter0WotWizard; END CalcPermutations; (* Merge the Set(s) returned by CalcPermutations and combine their probabilities; return the list of entries sorted by date(s) (occurDate with elements of type PropDate) or by id(s) (occurName with elements of type PropName) *) - PROCEDURE CalcEntries* (f: File; OUT occurDate, occurName: A.Tree): BOOLEAN; + PROCEDURE CalcEntries* (f: File; OUT permutations: INTEGER; OUT occurDate, occurName: A.Tree): BOOLEAN; VAR @@ -885,6 +883,8 @@ MODULE Duniter0WotWizard; debug := NIL; IF CalcPermutations(f, debug, sets) THEN + permutations := sets.NumberOfElems(); + (* Computing of Propagation(s) with their proba(s) *) A.New(occur); e := sets.Next(NIL); @@ -966,15 +966,15 @@ MODULE Duniter0WotWizard; VAR - ok, okP, b: BOOLEAN; + ok, okP, b, bb: BOOLEAN; pos, posI: S.CertPos; from, to: B.Pubkey; - toHash: S.Hash; - i, j, nbCertifs, princCertif: INTEGER; + toHash, h: S.Hash; + i, j, nbCertifs, princCertif, bnb: INTEGER; exp, date, mt, t: LONGINT; d: Dossier; c: Certif; - uid: B.String; + uid, uid1: B.String; certs, cert: PubList; cdL, l: CdList; proportionOfSentries: REAL; @@ -984,71 +984,77 @@ MODULE Duniter0WotWizard; dNb := 0; ok := S.IdNextHash(TRUE, toHash); WHILE ok DO - nbCertifs := 0; certs := NIL; - IF S.CertTo(toHash, pos) THEN - posI := pos; - REPEAT - okP := pos.CertNextPos(from, toHash); - IF okP THEN - b := S.Cert(from, toHash, to, exp) ; ASSERT(b, 100); - FixCertNextDate(from, date); - IF date <= exp THEN (* Not-expired certification *) - INC(nbCertifs); - NEW(cert); NEW(cert.pub); cert.pub^ := from; cert.date := date; - cert.next := certs; certs := cert; + b := S.IdHash(toHash, to, uid, exp); ASSERT(b); + b := B.IdPub(to, uid1); bb := B.IdUid(uid, to); + IF ~b & ~bb OR b & (uid$ = uid1$) & B.IdPubComplete(to, uid, b, h, bnb, exp) & (exp = BA.missing) THEN + nbCertifs := 0; certs := NIL; + IF S.CertTo(toHash, pos) THEN + posI := pos; + REPEAT + okP := pos.CertNextPos(from, toHash); + IF okP THEN + b := S.Cert(from, toHash, to, exp) ; ASSERT(b, 100); + FixCertNextDate(from, date); + IF date <= exp THEN (* Not-expired certification *) + INC(nbCertifs); + NEW(cert); NEW(cert.pub); cert.pub^ := from; cert.date := date; + cert.next := certs; certs := cert; + END; END; - END; - UNTIL ~okP; - END; - IF (nbCertifs >= minCertifs) & ((minCertifs < B.pars.sigQty) OR NotTooFar(certs, nbCertifs, princCertif, proportionOfSentries)) THEN - INC(dNb); - NEW(d); NEW(d.pub); - NEW(l.next); l := l.next; - l.cd := d; - IF minCertifs < B.pars.sigQty THEN - b := NotTooFar(certs, nbCertifs, princCertif, proportionOfSentries); + UNTIL ~okP; END; - d.princCertif := princCertif; - d.proportionOfSentries := proportionOfSentries; - b := S.IdHash(toHash, d.pub, d.id, d.limit); ASSERT(b, 101); - NEW(d.certifs, nbCertifs); - j := 0; - pos := posI; - okP := pos.CertNextPos(from, toHash); ASSERT(okP, 102); - REPEAT - b := S.Cert(from, toHash, to, exp); ASSERT(b, 103); - NEW(c); NEW(c.fromP); - c.fromP^ := from; - b := B.IdPub(from, c.from); ASSERT(b, 104); - FixCertNextDate(from, c.date); - c.limit := exp; - IF c.date <= c.limit THEN - d.certifs[j] := c; - INC(j); + IF (nbCertifs >= minCertifs) & ((minCertifs < B.pars.sigQty) OR NotTooFar(certs, nbCertifs, princCertif, proportionOfSentries)) THEN + INC(dNb); + NEW(d); NEW(d.pub); + NEW(l.next); l := l.next; + l.cd := d; + IF minCertifs < B.pars.sigQty THEN + b := NotTooFar(certs, nbCertifs, princCertif, proportionOfSentries); END; - okP := pos.CertNextPos(from, toHash); - UNTIL ~okP; + d.princCertif := princCertif; + d.proportionOfSentries := proportionOfSentries; + b := S.IdHash(toHash, d.pub, d.id, d.limit); ASSERT(b, 101); + NEW(d.certifs, nbCertifs); + j := 0; + pos := posI; + okP := pos.CertNextPos(from, toHash); ASSERT(okP, 102); + REPEAT + b := S.Cert(from, toHash, to, exp); ASSERT(b, 103); + NEW(c); NEW(c.fromP); + c.fromP^ := from; + b := B.IdPub(from, c.from); ASSERT(b, 104); + FixCertNextDate(from, c.date); + c.limit := exp; + IF c.date <= c.limit THEN + d.certifs[j] := c; + INC(j); + END; + okP := pos.CertNextPos(from, toHash); + UNTIL ~okP; + END; + ok := S.IdNextHash(FALSE, toHash); END; - ok := S.IdNextHash(FALSE, toHash); END; cNb := 0; ok := S.CertNextTo(TRUE, pos); WHILE ok DO - IF pos.CertNextPos(from, toHash) & S.Cert(from, toHash, to, exp) & B.IdPub(to, uid) THEN + IF pos.CertNextPos(from, toHash) & S.Cert(from, toHash, to, exp) THEN REPEAT - NEW(c); NEW(c.fromP); - c.fromP^ := from; - b := B.IdPub(from, c.from); ASSERT(b, 105); - c.to := uid; - FixCertNextDate(from, c.date); - c.limit := exp; - (* Si la certif n'est pas encore passée au dernier bloc alors qu'elle aurait dû passer à ce bloc ou avant, il y a peu de chance qu'elle passe plus tard et il vaut mieux l'enlever ; il faut aussi l'enlever si elle a dépassé sa date limite ; peut-être inutile maintenant *) - mt := 0; - b := B.TimeOf(B.LastBlock() - 1, mt, t); ASSERT(b OR (B.LastBlock() = 0), 106); - IF (c.date <= c.limit) & (c.date > mt) THEN - INC(cNb); - NEW(l.next); l := l.next; - l.cd := c; + IF B.IdPubComplete(to, uid, b, h, bnb, t) & b THEN + NEW(c); NEW(c.fromP); + c.fromP^ := from; + b := B.IdPub(from, c.from); ASSERT(b, 105); + c.to := uid; + FixCertNextDate(from, c.date); + c.limit := exp; + (* Si la certif n'est pas encore passée au dernier bloc alors qu'elle aurait dû passer à ce bloc ou avant, il y a peu de chance qu'elle passe plus tard et il vaut mieux l'enlever ; il faut aussi l'enlever si elle a dépassé sa date limite ; peut-être inutile maintenant *) + mt := 0; + b := B.TimeOf(B.LastBlock() - 1, mt, t); ASSERT(b OR (B.LastBlock() = 0), 106); + IF (c.date <= c.limit) & (c.date > mt) THEN + INC(cNb); + NEW(l.next); l := l.next; + l.cd := c; + END; END; UNTIL ~(pos.CertNextPos(from, toHash) & S.Cert(from, toHash, to, exp)); END; @@ -1070,7 +1076,7 @@ MODULE Duniter0WotWizard; END FillFile; (* Calculate the current set of entries, sorted by dates (occur) and by names (invOccur) *) - PROCEDURE BuildEntries* (OUT f: File; OUT cNb, dNb: INTEGER; OUT occurDate, occurName: A.Tree): BOOLEAN; + PROCEDURE BuildEntries* (OUT f: File; OUT permutations, cNb, dNb: INTEGER; OUT occurDate, occurName: A.Tree): BOOLEAN; VAR @@ -1080,7 +1086,7 @@ MODULE Duniter0WotWizard; BEGIN (*BuildEntries*) FillFile(B.pars.sigQty, f, cNb, dNb); n := 0; - b := CalcEntries(CopyFile(f, 0, n), occurDate, occurName); + b := CalcEntries(CopyFile(f, 0, n), permutations, occurDate, occurName); RETURN b; END BuildEntries; diff --git a/Standalone version/Sources/Duniter0/WotWizardPrint.txt b/Standalone version/Sources/Duniter0/WotWizardPrint.txt deleted file mode 100644 index 1d2302e..0000000 --- a/Standalone version/Sources/Duniter0/WotWizardPrint.txt +++ /dev/null @@ -1,389 +0,0 @@ -(* -Duniter: WotWizard. - -Copyright (C) 2017 GérardMeunier - -This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*) - -MODULE Duniter0WotWizardPrint; - - - - IMPORT - - A := UtilAvlTree, B := Duniter0Blockchain, BA := Duniter0Basic, Dialog, Math, TextMappers, TextModels, TextViews, W := Duniter0WotWizard, Views; - - VAR - - debugFo: TextMappers.Formatter; - - (* Print c with fo *) - PROCEDURE PrintCertif (IN fo: TextMappers.Formatter; c: W.Certif; now: LONGINT); - - VAR - - s: BA.DateTime; - - BEGIN (*PrintCertif*) - IF c.to # NIL THEN - fo.WriteString(c.to); fo.WriteString(" <-"); fo.WriteTab; - END; - fo.WriteString(c.from); - fo.WriteString(" "); - BA.TimestampToString(c.date, s); - fo.WriteString(s); - fo.WriteString(" (-> "); - BA.TimestampToString(c.limit, s); - fo.WriteString(s); - fo.WriteString(")"); - IF (c.date < now) & (now <= c.limit) THEN - fo.WriteString(" (OK)"); - ELSE - fo.WriteString(" (KO)"); - END; - END PrintCertif; - - (* Print d with fo *) - PROCEDURE PrintDossier (IN fo: TextMappers.Formatter; d: W.Dossier; now: LONGINT); - - VAR - - s: BA.DateTime; - certifiers: POINTER TO ARRAY OF B.Pubkey; - j, bnb: INTEGER; - exp: LONGINT; - b: BOOLEAN; - percent: REAL; - hash: B.Hash; - - BEGIN (*PrintDossier*) - fo.WriteInt(d.princCertif); fo.WriteString(" "); - fo.WriteString(d.id); - BA.TimestampToString(d.date, s); - fo.WriteString(" ("); fo.WriteString(s); - fo.WriteString(") (-> "); - BA.TimestampToString(d.limit, s); - fo.WriteString(s); - fo.WriteString(") ("); - IF d.certifs # NIL THEN - NEW(certifiers, LEN(d.certifs)); - FOR j := 0 TO LEN(d.certifs) - 1 DO - b := B.IdUid(d.certifs[j](W.Certif).from, certifiers[j], hash, bnb, exp); ASSERT(b); - END; - percent := B.PercentOfSentries(certifiers); - fo.WriteRealForm(percent * 100, 16, 1, - 2, " "); - fo.WriteString("%) ("); - IF (d.princCertif = B.pars.sigQty) & (now <= d.limit) & (percent >= B.pars.xpercent) THEN - fo.WriteString("OK"); - ELSE - fo.WriteString("KO"); - END; - ELSE - fo.WriteString("0%) (KO"); - END; - fo.WriteString(") |"); - IF d.certifs # NIL THEN - FOR j := 0 TO LEN(d.certifs) - 1 DO - fo.WriteLn; fo.WriteTab; - PrintCertif(fo, d.certifs[j](W.Certif), now); - END; - END; - END PrintDossier; - - (* Print f with fo, starting at the element of rank i0; if withNow, the output begins with the printing of the current date *) - PROCEDURE PrintFile (IN fo: TextMappers.Formatter; f: W.File; i0: INTEGER; withNow: BOOLEAN); - - VAR - - s: BA.DateTime; - now: LONGINT; - i: INTEGER; - cd: W.CertOrDoss; - - BEGIN (*PrintFile*) - now := B.Now(); - IF withNow THEN - BA.TimestampToString(now, s); - fo.WriteString(s); - fo.WriteString(" (UTC+0)"); - fo.WriteLn; fo.WriteLn; - END; - IF f # NIL THEN - FOR i := i0 TO LEN(f) - 1 DO - cd := f[i]; - WITH - |cd: W.Certif DO - PrintCertif(fo, cd, now); - |cd: W.Dossier DO - PrintDossier(fo, cd, now); - END; - fo.WriteLn; fo.WriteLn; - END; - fo.WriteLn; - END; - END PrintFile; - - (* Print permutations returned by CalcPermutations *) - PROCEDURE PrintPermutations (IN fo: TextMappers.Formatter; f: W.File); - - VAR - - n, i, l: INTEGER; - s, nowS: BA.DateTime; - sets: A.Tree; - e, ee: A.Elem; - debug: W.Debug; - - BEGIN (*PrintPermutations*) - debug := NIL; - IF W.CalcPermutations(f, debug, sets) THEN - fo.WriteString(" "); - BA.TimestampToString(B.Now(), nowS); - fo.WriteString(nowS); - fo.WriteString(" (UTC+0)"); - fo.WriteLn; fo.WriteLn; - e := sets.Next(NIL); - l := 0; - WITH e: W.Set DO - ee := e.t.Next(NIL); - WHILE ee # NIL DO - l := MAX(l, LEN(ee(W.Propagation).id$)); - ee := e.t.Next(ee); - END; - END; - WHILE e # NIL DO - WITH e: W.Set DO - fo.WriteString(" "); - fo.WriteMsg("#Duniter0:Proba"); fo.WriteString(" = "); - n := SHORT(ENTIER(Math.Round(e.proba * 10000))); - fo.WriteInt(n DIV 100); fo.WriteString("."); fo.WriteIntForm(n MOD 100, 10, 2, '0', FALSE); - fo.WriteString("%"); - fo.WriteLn; - ee := e.t.Next(NIL); - WHILE ee # NIL DO - WITH ee: W.Propagation DO - fo.WriteString(" "); - fo.WriteString(ee.id); - FOR i := 1 TO l - LEN(ee.id$) DO - fo.WriteString(" "); - END; - fo.WriteString(" ("); - BA.TimestampToString(ee.date, s); - fo.WriteString(s); - IF ee.after THEN - fo.WriteString("+"); - END; - fo.WriteString(")"); - fo.WriteLn; - END; - ee := e.t.Next(ee); - END; - END; - fo.WriteLn; - e := sets.Next(e); - END; - END; - END PrintPermutations; - - (* Print the entries sorted by dates *) - PROCEDURE ByDates* (IN fo: TextMappers.Formatter; occur: A.Tree); - - VAR - - l, i: INTEGER; - e: A.Elem; - date: LONGINT; - after: BOOLEAN; - s: BA.DateTime; - - BEGIN (*ByDates*) - l := 0; - e := occur.Next(NIL); - WHILE e # NIL DO - l := MAX(l, LEN(e(W.PropDate).id$)); - e := occur.Next(e); - END; - date := - 1; - e := occur.Next(NIL); - WHILE e # NIL DO - WITH e: W.PropDate DO - IF (e.date # date) OR (e.after # after) THEN - date := e.date; after := e.after; - fo.WriteString(" "); fo.WriteLn; - fo.WriteString(" "); - BA.TimestampToString(e.date, s); - fo.WriteString(s); - IF e.after THEN - fo.WriteString("+"); - END; - fo.WriteLn; - END; - fo.WriteString(" "); - fo.WriteString(e.id); - FOR i := 1 TO l - LEN(e.id$) DO - fo.WriteString(" "); - END; - fo.WriteString(": "); fo.WriteMsg("#Duniter0:Proba"); fo.WriteString(" = "); - fo.WriteIntForm(ENTIER(Math.Round(e.proba * 100)), 10, 3, " ", FALSE); - fo.WriteString("%"); - fo.WriteLn; - END; - e := occur.Next(e); - END; - END ByDates; - - (* Print the entries sorted by names *) - PROCEDURE ByNames* (IN fo: TextMappers.Formatter; invOccur: A.Tree); - - VAR - - id: B.String; - e: A.Elem; - ss: Dialog.String; - i: INTEGER; - s: BA.DateTime; - - BEGIN (*ByNames*) - NEW(id, 1); id^ := 0X; - e := invOccur.Next(NIL); - WHILE e # NIL DO - WITH e: W.PropName DO - IF e.id$ # id$ THEN - id := e.id; - fo.WriteString(" "); fo.WriteLn; - fo.WriteString(" "); - fo.WriteString(e.id); - fo.WriteLn; - END; - fo.WriteString(" "); - IF e.date = BA.never THEN - Dialog.MapString("#Duniter0:Never", ss); - fo.WriteString(ss); - BA.TimestampToString(0, s); - FOR i := 0 TO LEN(s$) - LEN(ss$) DO - fo.WriteString(" "); - END; - ELSE - BA.TimestampToString(e.date, s); - fo.WriteString(s); - IF e.after THEN - fo.WriteString("+"); - ELSE - fo.WriteString(" "); - END; - END; - fo.WriteString(": "); fo.WriteMsg("#Duniter0:Proba"); fo.WriteString(" = "); - fo.WriteIntForm(ENTIER(Math.Round(e.proba * 100)), 10, 3, " ", FALSE); - fo.WriteString("%"); - fo.WriteLn; - END; - e := invOccur.Next(e); - END; - END ByNames; - - (* Print the entries sorted by names first and then by dates *) - PROCEDURE PrintEntries (IN fo: TextMappers.Formatter; occur, invOccur: A.Tree); - - VAR - - nowS: BA.DateTime; - - BEGIN (*PrintEntries*) - BA.TimestampToString(B.Now(), nowS); - fo.WriteString(" "); - fo.WriteString(nowS); - fo.WriteString(" (UTC+0)"); - fo.WriteLn; - ByNames(fo, invOccur); - fo.WriteString(" "); fo.WriteLn; - ByDates(fo, occur); - END PrintEntries; - - (* Print the current W.File *) - PROCEDURE ShowFile*; - - VAR - - t: TextModels.Model; - fo: TextMappers.Formatter; - f: W.File; - cNb, dNb: INTEGER; - - BEGIN (*ShowFile*) - t := TextModels.dir.New(); - fo.ConnectTo(t); - Views.OpenView(TextViews.dir.New(t)); - W.FillFile(1, f, cNb, dNb); - PrintFile(fo, f, 0, TRUE); - END ShowFile; - - (* Print the set of current possible permutations of entries *) - PROCEDURE Permutations*; - - VAR - - t: TextModels.Model; - fo: TextMappers.Formatter; - f: W.File; - cNb, dNb: INTEGER; - - BEGIN (*Permutations*) - t := TextModels.dir.New(); - fo.ConnectTo(t); - Views.OpenView(TextViews.dir.New(t)); - W.FillFile(B.pars.sigQty, f, cNb, dNb); - PrintPermutations(fo, f); - END Permutations; - - (* Print the current set of entries, sorted by names first, then by dates *) - PROCEDURE Entries*; - - VAR - - t: TextModels.Model; - fo: TextMappers.Formatter; - f: W.File; - occur, invOccur: A.Tree; - cNb, dNb: INTEGER; - - BEGIN (*Entries*) - t := TextModels.dir.New(); - fo.ConnectTo(t); - Views.OpenView(TextViews.dir.New(t)); - W.FillFile(B.pars.sigQty, f, cNb, dNb); - IF W.CalcEntries(f, occur, invOccur) THEN - PrintEntries(fo, occur, invOccur); - END; - END Entries; - - PROCEDURE DoDebug (f: W.File; i0: INTEGER); - - BEGIN (*DoDebug*) - PrintFile(debugFo, f, i0, FALSE); - debugFo.WriteLn; - END DoDebug; - - PROCEDURE Debug* ; - - VAR - - t: TextModels.Model; - f: W.File; - b: BOOLEAN; - sets: A.Tree; - cNb, dNb: INTEGER; - - BEGIN (*Debug*) - t := TextModels.dir.New(); - debugFo.ConnectTo(t); - Views.OpenView(TextViews.dir.New(t)); - W.FillFile(B.pars.sigQty, f, cNb, dNb); - b := W.CalcPermutations(f, DoDebug, sets); - END Debug; - - END Duniter0WotWizardPrint. diff --git a/Standalone version/Sources/Util/Alea.txt b/Standalone version/Sources/Util/Alea.txt index f737984..324d7a9 100644 --- a/Standalone version/Sources/Util/Alea.txt +++ b/Standalone version/Sources/Util/Alea.txt @@ -81,7 +81,7 @@ MODULE UtilAlea; v2 := 2. * g.Random() - 1.; r := v1 * v1 + v2 * v2; UNTIL (r < 1.) & (r > 0.); - r := Math.Sqrt( - 2. * Math.Ln(r) / r); + r := Math.Sqrt( -2. * Math.Ln(r) / r); g.g := v1 * r; RETURN v2 * r; END; diff --git a/Standalone version/Sources/Util/Bab/Json.txt b/Standalone version/Sources/Util/Bab/Json.txt index 0a4e7e1..b8d8f79 100644 --- a/Standalone version/Sources/Util/Bab/Json.txt +++ b/Standalone version/Sources/Util/Bab/Json.txt @@ -1,5 +1,19 @@ +{ +Util: Utility tools. + +Copyright (C) 2017…2018 GérardMeunier + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} + BABEL UtilJson; + + DEFINITION digit = ['0'-'9'] ; diff --git a/Standalone version/Sources/Util/Net.txt b/Standalone version/Sources/Util/Net.txt new file mode 100644 index 0000000..e40f3de --- /dev/null +++ b/Standalone version/Sources/Util/Net.txt @@ -0,0 +1,278 @@ +(* +Util: Utility tools. + +Copyright (C) 2001…2006 GérardMeunier + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +MODULE UtilNet; + + (* Centrality calculation by the use of FloydWarshall algorithm (calculation of shortest distances) *) + + (* Le degré de centralité d'un membre est le nombre de couples orientés (membre->membre) pour lesquels il fait partie d'un des plus courts chemins reliant ce couple. *) + + + + IMPORT + + (* + L := StdLog, + *) + + S := UtilSets, UtilSort; + + CONST + + (* Results of comparison. *) + lt* = -1; (* less than *) + eq* = 0; (* equal *) + gt* = + 1; (* greater than *) + + infinity = MAX(INTEGER) DIV 2; + + TYPE + + Net* = POINTER TO ABSTRACT RECORD + nbNodes-: INTEGER; + nodes: NodesSort; + extremities: S.Set; + linksFT: Links; + dist: Distance; + END; + + Node* = POINTER TO ABSTRACT RECORD + END; + + Nodes = POINTER TO ARRAY OF Node; + + NodesSort = RECORD (UtilSort.T) + t: Nodes; + e: POINTER TO ARRAY OF BOOLEAN; + END; + + Links = POINTER TO ARRAY OF S.Set; + + SetC = POINTER TO ARRAY OF LONGINT; + + Distance = POINTER TO ARRAY OF POINTER TO ARRAY OF INTEGER; + + Centrals* = POINTER TO LIMITED RECORD + nbNodes: INTEGER; + nodes: Nodes; + extremities: S.Set; + extI: S.SetIterator; + cT: SetC; + pos: INTEGER; + END; + + PROCEDURE (net: Net) Number- (): INTEGER, NEW, ABSTRACT; + + PROCEDURE (net: Net) Enumerate- (first: BOOLEAN; OUT node: Node; OUT extremity: BOOLEAN): BOOLEAN, NEW, ABSTRACT; + + PROCEDURE (n1: Node) Compare- (n2: Node): BYTE, NEW, ABSTRACT; + + PROCEDURE (n: Node) FromTo- (first: BOOLEAN; OUT follow: Node): BOOLEAN, NEW, ABSTRACT; + + PROCEDURE (net: Net) ExtremitiesNb* (): INTEGER, NEW; + + BEGIN (*ExtremitiesNb*) + ASSERT(net.extremities # NIL, 20); + RETURN net.extremities.nbElems; + END ExtremitiesNb; + + PROCEDURE (VAR s: NodesSort) Less (p1, p2: INTEGER): BOOLEAN; + + BEGIN (*Less*) + RETURN s.t[p1].Compare(s.t[p2]) = lt; + END Less; + + PROCEDURE (VAR s: NodesSort) Swap (p1, p2: INTEGER); + + VAR + + n: Node; + b: BOOLEAN; + + BEGIN (*Swap*) + n := s.t[p1]; s.t[p1] := s.t[p2]; s.t[p2] := n; + b := s.e[p1]; s.e[p1] := s.e[p2]; s.e[p2] := b; + END Swap; + + PROCEDURE (ct: Centrals) Walk* (first: BOOLEAN; OUT node: Node; OUT c: LONGINT): BOOLEAN, NEW; + + VAR + + ok: BOOLEAN; + + BEGIN (*Walk*) + IF first THEN + ok := ct.extI.FirstE(ct.pos); + ELSE + ok := ct.extI.NextE(ct.pos); + END; + IF ~ok THEN + RETURN FALSE; + END; + node := ct.nodes[ct.pos]; + c := ct.cT[ct.pos]; + RETURN TRUE; + END Walk; + + PROCEDURE (net: Net) FindNode (node: Node; OUT n: INTEGER): BOOLEAN, NEW; + + BEGIN (*FindNode*) + n := net.nbNodes; + net.nodes.t[n] := node; + net.nodes.BinSearch(0, n - 1, n); + RETURN n < net.nbNodes; + END FindNode; + + PROCEDURE (net: Net) FloydWarshall, NEW; + + VAR + + i, j, k: INTEGER; + ok: BOOLEAN; + iter: S.SetIterator; + + BEGIN (*FloydWarshall*) + NEW(net.dist, net.nbNodes); + FOR i := 0 TO net.nbNodes - 1 DO + NEW(net.dist[i], net.nbNodes); + FOR j := 0 TO net.nbNodes - 1 DO + net.dist[i, j] := infinity; + END; + iter.Attach(net.linksFT[i]); + ok := iter.FirstE(j); + WHILE ok DO + net.dist[i, j] := 1; + ok := iter.NextE(j); + END; + net.dist[i, i] := 0; + END; + FOR k := 0 TO net.nbNodes - 1 DO + FOR i := 0 TO net.nbNodes - 1 DO + FOR j := 0 TO net.nbNodes - 1 DO + net.dist[i, j] := MIN(net.dist[i, j], net.dist[i, k] + net.dist[k, j]); + END; + END; + END; + END FloydWarshall; + + PROCEDURE (net: Net) Update*, NEW; + + VAR + + i, n: INTEGER; + ok, extremity, b: BOOLEAN; + node: Node; + + BEGIN (*Update*) + net.nbNodes := net.Number(); + NEW(net.nodes.t, net.nbNodes + 1); + NEW(net.nodes.e, net.nbNodes); + i := 0; + ok := net.Enumerate(TRUE, node, extremity); + WHILE ok DO + net.nodes.t[i] := node; + net.nodes.e[i] := extremity; + INC(i); + ok := net.Enumerate(FALSE, node, extremity); + END; + ASSERT(i = net.nbNodes); + net.nodes.QuickSort(0, net.nbNodes - 1); + net.extremities := S.NewSet(); + FOR i := 0 TO net.nbNodes - 1 DO + IF net.nodes.e[i] THEN + net.extremities.Incl(i); + END; + END; + net.nodes.e := NIL; + + NEW(net.linksFT, net.nbNodes); + FOR i := 0 TO net.nbNodes - 1 DO + net.linksFT[i] := S.NewSet(); + END; + FOR i := 0 TO net.nbNodes - 1 DO + ok := net.nodes.t[i].FromTo(TRUE, node); + WHILE ok DO + b := net.FindNode(node, n); ASSERT(b); + net.linksFT[i].Incl(n); + ok := net.nodes.t[i].FromTo(FALSE, node); + END; + END; + + net.FloydWarshall; + END Update; + + PROCEDURE (net: Net) Centrality* (node: Node): LONGINT, NEW; + + VAR + + en, i, j: INTEGER; + count: LONGINT; + oki, okj: BOOLEAN; + iteri, iterj: S.SetIterator; + + BEGIN (*Centrality*) + IF ~net.FindNode(node, en) THEN + RETURN 0; + END; + count := 0; + iteri.Attach(net.extremities); iterj.Attach(net.extremities); + oki := iteri.FirstE(i); + WHILE oki DO + IF i # en THEN + okj := iterj.FirstE(j); + WHILE okj DO + IF (en # j) & (net.dist[i, en] + net.dist[en, j] = net.dist[i, j]) THEN + INC(count); + END; + okj := iterj.NextE(j); + END; + END; + oki := iteri.NextE(i); + END; + RETURN count; + END Centrality; + + PROCEDURE (net: Net) NewC (OUT set: SetC), NEW; + + VAR + + i: INTEGER; + + BEGIN (*NewC*) + NEW(set, net.nbNodes); + FOR i := 0 TO net.nbNodes - 1 DO + set[i] := 0; + END; + END NewC; + + PROCEDURE (net: Net) Centralities* (): Centrals, NEW; + + VAR + + setC: SetC; + ct: Centrals; + i: INTEGER; + + BEGIN (*Centralities*) + net.NewC(setC); + FOR i := net.nbNodes - 1 TO 0 BY - 1 DO + setC[i] := net.Centrality(net.nodes.t[i]); + END; + NEW(ct); + ct.nbNodes := net.nbNodes; + ct.nodes := net.nodes.t; + ct.extremities := net.extremities; ct.extI.Attach(ct.extremities); + ct.cT := setC; + RETURN ct; + END Centralities; + + END UtilNet. diff --git a/Standalone version/Sources/Util/Sets.txt b/Standalone version/Sources/Util/Sets.txt index 67a7929..ca8c069 100644 --- a/Standalone version/Sources/Util/Sets.txt +++ b/Standalone version/Sources/Util/Sets.txt @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with thi MODULE UtilSets; - (**) + (* The module UtilSets implements the type Set, a set of non-negative integers, represented by intervals. *) @@ -34,12 +34,17 @@ MODULE UtilSets; END; Set* = POINTER TO LIMITED RECORD (* Set of non-negative integers. *) - nbElems-, (* Number of elements in the set. *) - pos, posE: INTEGER; - elems, cour: Segment; + nbElems-: INTEGER; (* Number of elements in the set. *) + elems: Segment; END; TableVer = ARRAY 2, 2 OF BYTE; + + SetIterator* = RECORD + s: Set; + cour: Segment; + pos, posE: INTEGER; + END; PROCEDURE InsereSegment (apresSeg: Segment; plein, vide: INTEGER); @@ -65,7 +70,6 @@ MODULE UtilSets; s.elems.largeurs[0] := taSet; s.elems.suivant := s.elems; s.elems.precedent := s.elems; - s.cour := NIL; END Empty; (* Creates and returns a new empty set. *) @@ -117,7 +121,6 @@ MODULE UtilSets; BEGIN (*Trans*) s.nbElems := src.nbElems; s.elems := src.elems; - s.cour := NIL; END Trans; (* Creates and returns a copy of s.*) @@ -539,89 +542,84 @@ MODULE UtilSets; RETURN se # t; END NextElem; + PROCEDURE (VAR i: SetIterator) Attach* (s: Set), NEW; + + BEGIN (*Attach*) + ASSERT(s # NIL, 20); + i.s := s; + i.cour := NIL; + END Attach; + (* On return, min and max contain the first interval of the set s. Returns TRUE if such an interval exists. Usage: ok:= s.First(a, b); WHILE ok DO ... ok:= s.Next(a, b) END; *) - PROCEDURE (s: Set) First* (OUT min, max: INTEGER): BOOLEAN, NEW; + PROCEDURE (VAR i: SetIterator) First* (OUT min, max: INTEGER): BOOLEAN, NEW; BEGIN (*First*) - IF s.IsEmpty() THEN + ASSERT(i.s # NIL, 20); + IF i.s.IsEmpty() THEN RETURN FALSE; END; - s.cour := s.elems.suivant; - s.pos := sMin + s.elems.largeurs[0]; - min := s.pos; - max := min + s.cour.largeurs[1] - 1; + i.cour := i.s.elems.suivant; + i.pos := sMin + i.s.elems.largeurs[0]; + min := i.pos; + max := min + i.cour.largeurs[1] - 1; RETURN TRUE; END First; (* On return, min and max contain the next interval of the set s. Returns TRUE if such an interval exists. s.First must have been called once before s.Next. Usage: ok:= s.First(a, b); WHILE ok DO ... ok:= s.Next(a, b) END; *) - PROCEDURE (s: Set) Next* (OUT min, max: INTEGER): BOOLEAN, NEW; + PROCEDURE (VAR i: SetIterator) Next* (OUT min, max: INTEGER): BOOLEAN, NEW; BEGIN (*Next*) - ASSERT(s.cour # NIL, 20); - s.pos := s.pos + s.cour.largeurs[1] + s.cour.largeurs[0]; - s.cour := s.cour.suivant; - IF s.cour = s.elems THEN - s.cour := NIL; + ASSERT(i.s # NIL, 20); + ASSERT(i.cour # NIL, 21); + i.pos := i.pos + i.cour.largeurs[1] + i.cour.largeurs[0]; + i.cour := i.cour.suivant; + IF i.cour = i.s.elems THEN + i.cour := NIL; RETURN FALSE; END; - min := s.pos; - max := min + s.cour.largeurs[1] - 1; + min := i.pos; + max := min + i.cour.largeurs[1] - 1; RETURN TRUE; END Next; - PROCEDURE (s: Set) FirstE* (OUT e: INTEGER): BOOLEAN, NEW; + PROCEDURE (VAR i: SetIterator) FirstE* (OUT e: INTEGER): BOOLEAN, NEW; BEGIN (*FirstE*) - IF s.IsEmpty() THEN + ASSERT(i.s # NIL, 20); + IF i.s.IsEmpty() THEN RETURN FALSE; END; - s.cour := s.elems.suivant; - s.pos := sMin + s.elems.largeurs[0]; - s.posE := s.pos; - e := s.pos; + i.cour := i.s.elems.suivant; + i.pos := sMin + i.s.elems.largeurs[0]; + i.posE := i.pos; + e := i.posE; RETURN TRUE; END FirstE; - PROCEDURE (s: Set) NextE* (OUT e: INTEGER): BOOLEAN, NEW; + PROCEDURE (VAR i: SetIterator) NextE* (OUT e: INTEGER): BOOLEAN, NEW; VAR max: INTEGER; BEGIN (*NextE*) - ASSERT(s.cour # NIL, 20); - max := s.pos + s.cour.largeurs[1] - 1; - IF s.posE < max THEN - INC(s.posE); - e := s.posE; + ASSERT(i.s # NIL, 20); + ASSERT(i.cour # NIL, 21); + max := i.pos + i.cour.largeurs[1] - 1; + IF i.posE < max THEN + INC(i.posE); + e := i.posE; RETURN TRUE; END; - s.pos := s.pos + s.cour.largeurs[1] + s.cour.largeurs[0]; - s.cour := s.cour.suivant; - IF s.cour = s.elems THEN - s.cour := NIL; + i.pos := i.pos + i.cour.largeurs[1] + i.cour.largeurs[0]; + i.cour := i.cour.suivant; + IF i.cour = i.s.elems THEN + i.cour := NIL; RETURN FALSE; END; - s.posE := s.pos; - e := s.posE; + i.posE := i.pos; + e := i.posE; RETURN TRUE; END NextE; - PROCEDURE (s: Set) NbOfElems* (): INTEGER, NEW; - - VAR - - n, min, max: INTEGER; - ok: BOOLEAN; - - BEGIN (*NbOfElems*) - n := 0; - ok := s.First(min, max); - WHILE ok DO - INC(n, max - min + 1); - ok := s.Next(min, max); - END; - RETURN n; - END NbOfElems; - END UtilSets.