петък, 21 юни 2013 г.

Размишления върху Конституцията

Слушайки напоследък как политиците като едни неуморни пчели, цял ден събирали прашец от нечия лимонова овощна градина, кисело обясняват как ще пренапишат изцяло Избирателния кодекс, защото така искало Гражданското общество, ми се доповръща като на пасажер, намиращ се в брулена от силен страничен вятър Лада в завой. Твърде рядко получавам позиви за прочистване на храносмилателния тракт едновременно в двете посоки, поради което прегърнах появилата се възможност и се възползвах от нея. След като почистих старателно местообитанието си и себе си, си сипах едно питие, което ми помогна да възстановя жизнените си показатели до що-годе поносими равнища. И тъй като историческите сведения показват, че Онези избраните няма да помислят вместо мен, започнах да мисля.

Какво му е лошото на Избирателния кодекс?

Като за начало, нека да разгледаме защо имаме Избирателен кодекс? Ами за да пише в него правилата за избор. Избор на какво? Ами да погледнем в Конституцията:

Чл. 8. казва, че "Държавната власт се разделя на законодателна, изпънителна и съдебна". Аз като един лаик инжинер, не-завършил Право в СУ, очаквам тези 3 поименно изброени власти да са независими една от друга -- иначе защо ще ги изброяват поотделно, можеше да се каже само, че има държавна власт и това е. А след като съгласно Чл. 1, ал. 1. "...цялата държавна власт произтича от народа", аз очаквам, народа да има възможност да си ги избира независимо една от друга.


Въоръжен с непрекършваем оптимизъм в светлото бъдеще чета нататък, за да се ориентирам какво точно идва да каже "законодателна", "изпълнителна" и "съдебна" власт. Установявам, че никъде не се споменава какво правят тези три власти и какви са органите им, освен в чл. 62, ал. 1. "Народното събрание осъществява законодателната власт и упражнява парламентарен контрол". Никъде не се споменава напр., че Министерския съвет упражнява изпълнителната власт, или какви са органите на съдебната власт. Всички нейни институции, като Висш съдебен съвет, прокуратура, следствие и т.н. се въвеждат в летящ старт, без да стане нясно кой какъв е и защо съществува.

Добре, казвам си, сигурно прекалено формално гледам на нещата. Сигурно тия работи, дето не са написани конкретно се подразбират и се учат във втори клас, пък аз съм ги пропуснал, щото съм бил келеш. Дай поне да видим дали са независими.

Първото нещо, което бие на очи е, че в Конституцията думата "независим" и нейните производни се срещат по-рядко, отколкото думата "мерцедес" в произволно чалга произведение. Никъде не се споменава изрично, че трите власти от чл. 8 са всъщност независими. От чл. 117, ал. 2 става ясно единствено, че "Съдебната власт е независима. При осъществяване на своите функции съдиите, съдебните заседатели, прокурорите и следователите се подчиняват само на закона". Това поражда въпроси: Независима от какво? А останалите 2 власти зависими ли са? От какво? Защо няма реципрочни текстове за останалите власти? Или при осъществяване на своите функции участниците в останалите 2 власти се подчиняват и на други неща, освен закона?


Добре де, не са го споменали изрично. Но сигурно поне се избират независимо? Да, ама не. И няма нужда да четем Конституцията -- всички сме били на избори. Защо се избират пряко от народа само представителите на законодателната власт? Защо изпълнителната власт е функция от законодателната (парламента избира правителство)? Защо органите на съдебната власт също са функция от законодателната и на Президентската институция? Това пък последното какво беше и защо не е в списъка на чл. 8?

И въобще: какво се занимаваме с Изборен кодекс, след като Конституцията все едно е писана от полуграмотни четвъртокласници, които никога не са чували за аксиоматичен базис и причинно-следствена връзка? Моето лично мнение е, че първото нещо, което трябва да се направи е да се промени Конституцията, поне в следните й части:

  • ясна дефиниция на това с какво се занимават трите власти (законодателна, изпълнителна и съдебна) и какви са техните органи и как се формира техния бюджет;
  • пряк избор от народа на всеки един от съответните органи (народно събрание, ръководства на органите на изпълнителната власт и ръководства на органите на съдебната власт);
  • премахване на синекурни длъжности като Президент, който формално погледнато не е част от държавната власт, поне не и съгласно чл. 8. Вместо това приемливо би било например органът на изпълнителната власт да се нарече Президент (напр. както в САЩ, Франция и т.н.);
Въобще не съм засегнал темата за местната власт. Тя също ли се дели на тези трите, подобно на държавната? Ако да, за нея също важат горните точки. Защо напр. не си избираме районен съдя или районен прокурор? Ако не -- защо не? 

След това идват въпроси по конкретиката как да стане избора. Например, нека разгледаме случая с гласуване за законодателна власт. Напоследък тезата как "управляващите нямат никаква връзка с избирателите" присъства в публичното пространство с упоритостта на третирана с хомеопатия венерическа болест. Прост преглед на изборните системи ще покаже, че многомандатните избирателни райони (какъвто е случая в РБ) водят точно до това -- тъй като гласуваме за партийни листи, нямаме никаква представа кои са ни представителите всъщност, т.е. нямаме никаква връзка с тях. И си мисля, че когато улицата говори за "мажоритарна система", сигурно хората имат предвид въвеждането на едномандатни райони. Много е просто -- разделяме страната на райони, напр. използваме като база съществуващите общини, и всеки район излъчва по 1 народен представител напр. на 30 000 души, но поне по 1 за община. Съгласно текущите цифри, това би увеличило броя на народните представители, обаче ако това е проблем -- нека намалим броя на общините? В рамките на района, всеки избирател гласува за конретно лице, което да го представлява. И в последствие знае конкретно към кой да се обърне, за да му решава проблемите. И няма такива филми "А. Б. е водач на листите в 23, 12 и 18-ти район". WTF? Шизофрения нещо? И освен това, ако някой престане да бъде депутат, просто се провеждат избори наново в съответния район, а не "на неговото място влиза следващия от листата". Няма парламентарни групи, няма номадство, несъвместимости и  т.н. ушна кал в промишлени количества. Ако събереш 1000 подписа се кандидатираш за района и това е -- хората гласуват (или не гласуват) за тебе.

Редовният вой на политиците срещу едномандатните райони е, че бавно и полека те водят до двупартиен модел (виж Великобритания и САЩ, където тази система се прилага). А дали това е лошо? Не знам дали е лошо, но със сигурност според мен е по-добро от това, което имаме в момента.

Да обобщя: моето лично мнение, е че промени в Конституцията в духа на горното е това, което ни трябва. След това ще се занимаваме с Изборен кодекс. Всичко останало е не по-различно от пластична хирургия, извършена посредством клепане с баданарката или ремонт на печатна платка с SMB монтаж посредством заварки с поялника за улуци.

неделя, 9 юни 2013 г.

SBCL за ARM Част III

Пръдължение на това: Част II

От последния път добавих в src/compiler/arm/params.lisp още един enum, който дефинира константите, използвани за разграничаване на различните софтуерни прекъсвания. За какво става въпрос: понякога се налага  в lisp кода да се генерира прекъсване, което да бъде обработено от C runtime-а. Такива са например ситуациите, в които се генерира грешка, breakpoint, halt на виртуалната машина и т.н. Като гледам останалите платформи това се реализира чрез инструкция, която да доведе до генериране на SIGILL или SIGTRAP от страна на ОС и този сигнал се прихваща и обработва от специална функция в C runtime-а. Е, за да може да разбере тази функция какъв точно е повода за прекъсването, е необходимо това да бъде записано около (а най-добре във) инструкцията. Ще му мислим за това като му дойде времето, засега копираме списъка с trap-ове от някоя друга платформа.

Оказва се, че следващият платформено-зависим файл, src/compiler/arm/backend-params.lisp е продължение на params, разделено от основния файл по някое време в далечното минало, понеже е съдържало зависимости от конкретна структура, наречена BACKEND, която се е компилирала след params. Тази структура отдавна вече не съществува, така че разделението вече е само по исторически причини. Биха могли нещата да се merge-нат обратно в params, но някой друг път (трябва да се направи за всички платформи и да се махне backend-params изобщо). Тук се дефинират неща като:

  • *backend-byte-order*, което показва дали архитектурата е little endian или big endian (в нашия случай -- :little-endian);
  • *backend-page-size*, което е размера на страниците в паметта (засега слагаме 4096, колкото да има нещо, а като стигнем до използването й, ще установим правилната стойност по емпиричен път);
  • и разни други константи, свързани с garbage collection–а, които за сега само копираме, те би трябвало само да доведат до евентуална оптимизация, но според мен би следвало като първо приближение да работи и със стойностите от другите платформи;
Следващият файл, който трябва да разгледаме е src/compiler/arm/vm.lisp. Тъй като там работите стават сериозни и влизаме надълбокото, ще го оставя за другия път. За днес толкова :-)

събота, 1 юни 2013 г.

SBCL за ARM Част II

Продължение на това: Част I

Гледайки build-order.lisp-expr, първия изцяло платформено зависим файл, който се зарежда е src/compiler/arm/params.lisp. Тук се дефинират основни [константни] параметри на платформата, като например:

  • (def!constant n-word-bits 32) -- брой битове в една дума, където под дума се разбира 1 lisp descriptor. Какво точно е lisp descriptor? Това е основната "кукичка" към данните в SBCL. Ако данната се събира в 1 дескриптор, тя е самодостатъчна (такива са например т.н. fixnum числа). Ако данната не се събира в 1 дескриптор, то дескриптора съдържа пойнтер към паметта, където се съдържа останалата част от данните. И в двата случая една част от дескриптора указва типа на данните, но за това после. Забележете, че тук (и на много други места) се използва def!constant вместо стандартното defconstant, тък като тази версия се грижи да прави необходимите неща в зависимост от това кога точно се изпълнява (напр. по време на компилиране на крос-компилатора, дефинира не една, а две константи -- едната за да може host компилатора да знае за тази константа и да я разбира в последствие, другата за самия cross компилатор, който също трябва да си я запише някъде и да я използва когато той компилира);
  • (def!constant n-machine-word-bits 32) -- брой битове в думата, където под дума се разбира естествения тип данни за съответната архитектура. Аз лично не знам кому е нужно n-word-bits да е различно от n-machine-word-bits, но това е факт за alpha порт-а.
  • (def!constant n-byte-bits 8) -- малко безмислен параметър съгласно съвременните разбирания, но като се има предвид, че SBCL наследява code base от началото на 80-те години на миналия век, който пък не е ясно какво точно наследява, мога да си представя случаи, в които байтът не е бил 8 бита...
  • следващите няколко дефинират floating point форматите, които се поддържат native от платформата; в случая с ARM те изцяло съвпадат с IEEE 754 single и double float (при x86 напр. има и long-double, който се поддържа от хардуера, но тук -- не):
  • (def!constant float-sign-shift 31) -- колко наляво трябва да се шифтне бита за знак, за да застане на мястото си във floating point формата. Използва се и за single и за double, като за double  се прилага за старшата дума;
  • (def!constant single-float-bias 126)-- колко трябва да се прибави към експонентата, когато тя се кодира в съответния формат (виж IEEE 754);
  • (defconstant-eqx single-float-exponent-byte (byte 8 23) #'equalp) -- коя част от кодираните данни заема експонентата. (byte size pos) е стандартна lisp конструкция, която избира size на брой бита, започвайки от позиция pos. Странният начин за дефиниране на константата тук (и на други места) е свързан с факта, че това всъщност не е точно immediate константа, а е по-сложен Lisp обект, чиято стойност по време на компилация и после по време на зареждане може да се различава, която пък противоречи на смисъла "константа". Затова се ползва къстъм версия на defconstant.
  • (def!constant single-float-normal-exponent-min 1)
  • (def!constant single-float-normal-exponent-max 254) -- минимална и максимална стойност на експонентата за нормализирани числа;
  • (def!constant single-float-hidden-bit (ash 1 23)) -- съгласно IEEE 754 най-старшия бит на мантисата по подразбиране е 1 и не се записва;
  • (def!constant single-float-trapping-nan-bit (ash 1 22)) -- пак съгласно IEEE 754, когато има NaN (not-a-number), който води до грешка (trapping nan), то съответния бит е вдигнат;
  • Аналогични константи се дефинират и за double
Друг набор от изключително важни параметри, дефинирани тук е списък с адресите и размерите на различните "пространства". SBCL разделя паметта, която вижда, на няколко различни области, всяка с различно предназначение. Най-важните са т.н. static и dynamic space, като в static space се записват неща, които са предварително (разбирай -- още по време на компилацията на компилатора) алокирани и не се местят, докато в dynamic space се записват всички динамично създадени обекти. Както се досещате, в dynamic space-а работи garbage collector–а. В SBCL има имплементирани 2 гарбидж колектора -- класическият Cheney GC (и като казвам класически имам предвид, че е публикуван през 1970 г.) и по-нов, generational conservative garbage collector (gencgc). В зависимост от операционната система и вида GC тези пространства имат различни адреси и размери, при това се нагласят емпирично. За целта обаче трябва да тръгне SBCL на таргет машината, т.е. емпирично ще разберем правилните стойности доста по-късно, чак към момента на пускане на make-target-2.sh. Засега слагаме някакви стойности, колкото да ги има.

Следва списък от символи (разбирай -- променливи и функции), които да се запишат в static space-а, при това списъка е подреден. Тъй като те са непреместваеми, SBCL знае как да ги реферира като събере началото на статичното пространство с число, формирано от поредния номер на символа, умножено по размера на символа в паметта (който за щастие е константен ;-)). За момента не знаем кои символи ще ни трябват и кои не -- оставяме ги така, както са в X86 порта.

С това src/compiler/arm/params.lisp приключва. Ще трябва да го навестим някъде в бъдещето, когато стигнем до make-target-2.sh. Но засега -- това е.