sunnuntai 19. lokakuuta 2008

PEG - kielioppi

Minulla on ensimmäisen vaiheen toteutus hyvässä (rauhallisessa) vauhdissa. Ihan maistiaisiksi esittelen raakile-kieliopin lojban-teksteille. Näen jo, että siinä on puutteita ainakin tiettyjen "terminaattoritapausten" tunnistamisessa. Mutta haluan täydentää ja päivittää sitä iteratiivisesti, koska sen koko kasvaa joka tapauksessa ainakin viisikertaiseksi, ennen kuin se tukee "koko lojban-kieltä". Täydelliseen PEG (Parsing Expression Grammar) -kielioppiin verrattuna on huomioitava, että tämä kielioppi ei etene merkkitasolle asti, vaan teen "tokenizing"-operaation ensin, eli erittelen bridin sanat toisistaan. Lisäksi käytän erikoisfunktiota esim. tunnistamaan gismut.

Toinen kielioppi on edellisen kieliopin "metakielioppi", jonka avulla luen ohjelmallisesti ajonaikaisesti tuon lojban-kieliopin ja alustan "sääntöoliot" metakieliopin suorittaman parsimisen tuloksena. Metakielioppi sen sijaan on C++ -tasolla "kovakoodattu"


//
// PEG Grammar for a small subset of lojban language
//
// V.0.1
//
// ========= Notation =========
//
// [Symbol] := [Rule]
// &( ) and predicate
// !( ) not predicate
// ( )+ one or more
// ( )* zero or more
// ( )? zero or one
// E1 | E2 ordered choice
// E1 E2 sequence
//
//

// High level syntax

EBridi := (EBridiStart)? EBridiBody (EConnBridi)* // multiple connected bridi
EBridiStart := ".i" | "ni'o" // bridi start cmavo
EConnBridi := EBridiConnective EBridiBody // connected extension
EBridiConnective := ".ije" | "ri'a" | "ki'i" // bridi connectors
EBridiBody := (EBridiComp)+ // multiple
EBridiComp := ESumtiComp | ESelbriComp // Sumti- or selbri-phrase

// Selbri syntax

ESelbriComp := ("cu")? (ESpatiTempAttr)? (EConversCmavo)? EBrivla
EConversCmavo := "se" | "te" | "ve" | "xe"

// Sumti syntax

ESumtiComp := ESumtiPhrase | ESumtiTcita
ESumtiPhrase := ESingleSumtiPhr (EConnectedSumti)?
EConnectedSumti := ESumtiConnective ESingleSumtiPhr
ESumtiConnective := ".e" | ".a" | "joi" | "ce" | "ce'o"
ESingleSumtiPhr := (ESpatiTempAttr)? (ESumtiObject) (EIndirectDescrip)?
ESpatiTempAttr := "mu'o" | "ca" | "pu" | "ba" | "vi" | "va" | "vu" | "ga'u" | "ni'a" | "ca'u" | "ti'a"
ESumtiObject := EProSumti | ENamePhrase | ESelbriPlace | EAbstraction
EProSumti := "ko'i" | "ko'a" | "ko'e" | "fo'a" | "ri"
ENamePhrase := "la" EName (EProSumAssign)?
ESelbriPlace := (EPlaceTag)? EBrivlaEpress (EProSumAssign)?
EBrivlaEpress := EArticle EBrivla
EPlaceTag := "fa" | "fe" | "fi" | "fo" | "fu"
EArticle := "lo" | "le" | "lo'i" | "lei" | "le'i"
EBrivla := EGismu | ELujvo
EProSumAssign := "goi" EProSumti
EAbstraction := EArticlAbstract EAbstrPhrase
EArticlAbstract := "lenu" | "lonu"
EAbstrPhrase := EBrivla | EBridiBody
EIndirectDescrip := EAssosiation | ERelativeClause
EAssosiation := EAssosCmavo ESingleSumtiPhr
EAssosCmavo := "pe" | "po" | "po'e" | "po'u" | "ne" | "no'u"
ESumtiTcita := ESpatiTempAttr ESpatiTempExpr
ESpatiTempExpr := EAbstraction | EBrivlaEpress
ENamePhrase := ExplicitFunction_N
EGismu := ExplicitFunction_G
ELujvo := ExplicitFunction_L




//
// PEG Grammar for the PEG Grammar syntax
// "a meta grammar"
//
// V.0.1
//
// ========= Notation =========
//
// [Symbol] := [Rule]
// &( ) and predicate
// !( ) not predicate
// ( )+ one or more
// ( )* zero or more
// ( )? zero or one
// E1 | E2 ordered choice
// E1 E2 sequence
//
//

EGrammarLine := ECommentLine | ERuleClause
ECommentLine := "//" ECommentText
ERuleClause := ESymbol ":=" ERule (ECommentLine)?
ERule := ESequence | EChoice
ESequence := (ESequenceTerm)+
EChoice := EChoiceTerm EMoreChoice
ESequenceTerm := ESimppelTerm | EOperatorTerm
ESimppelTerm := ESymbol | ETerminal
EOperatorTerm := EZOne | EZMore | EOneMore | ENot | EAnd
EZOne := "(" ESimppelTerm ")?"
EZMore := "(" ESimppelTerm ")*"
EOneMore := "(" ESimppelTerm ")+"
ENot := "!(" ESimppelTerm ")"
EAnd := "&(" ESimppelTerm ")"
ESymbol := ExplicitFunction_S
ETerminal := ExplicitFunction_T

tiistai 14. lokakuuta 2008

Loebner Prize 2008

Loebner Prize 2008 -kisat on saatu päätökseen ja ainakin yhden analyysin mukaan se päivä on lähellä, jolloin joku osanottaja-botti häämää tuomareita riittävästi selviytyen kisan versiossa "Turing testistä".

http://technology.timesonline.co.uk/tol/news/tech_and_web/article4934858.ece

Kisassa siis tuomarit yrittävät selvittää kuka "teletypeyhteyden" päässä olevista on oikea ihminen ja kuka on tietokoneohjelma.
Mutta jos vaikka ensi vuonna joku ohjelma osaa viisi minuuttia hämätä riittävän montaa tuomaria ja voittaa pääpalkinnon, en silti noteeraa tätä "ihmisveroisena älykkyytenä". Olen tätä mieltä siksi, että valitettavasti tällaisessa kilpailussa pärjää paremmin erilaisilla hämäystaktiikoilla kuin yrittämällä luoda oikean kognitiivisen järjestelmän. Luulen, että kilpailun suurin virhe on juuri se, että koneen pitäisi valehdella olevan ihminen. Miksi valehtelu palkitaan? Kuvaako se jotenkin, tahattomasti, kulttuuriamme?

Minusta pitäisi kehittää uusi versio kilpailusta, jossa heti tiedetään kuka on ohjelmisto ja ja kuka oikea ihminen, mutta kaikille teetetään oikeita tehtäviä eikä smalltalk-keskusteluita. Ja jos ohjelmisto selviää luovaa, sponttania verbaalisesti käynnistettyä asiakokonaisuuksien omaksumista ja niihin liittyvää ongelmanratkaisua sisältyvistä monipuolisesta tehtäväjoukosta paremmin kuin inhimillisten referenssikipailijoiden enemmistö, niin ohjelma on kognitiivisilta kyvyiltään ihmisen tasolla. Smalltalk-tasoista (iltapäivälehti-) yleistietoa ei saisi edellyttää, koska se ei voi olla tärkeää. Luonnontieteellinen maailmankuva ja perustiedot ihmisyhteiskunnasta voisi silti olla vaatimuksena. Kysymyksessä olisi siis YO-kirjoitusten reaalikoe-tyyppinen tehtävistö. Tehtäviä voisi olla esim. 30kpl. Helpoimmat olisivat 10v ikäiselle koululaiselle sopivia ja vaikeimmat akateemisen peruskoulutuksen hankkineiden tasoa, vaikeutuen asteittain. Jokaiseen tehtävään kuuluisi laajahko tehtävänanto, asetelman kuvaus, jonka sekä ihmisen että botin olisi ymmärrettävä. Ymmärrystä ja taustatietoja pitäisi sitten osata soveltaa luovalla tavalla annetun tehtävän ratkaisemisessa.

Itse asiassa voisi olla kaksi sarjaa: toinen englannintaitoiselle botille ja toinen sellaiselle, joka osaa vain lojbania...

perjantai 26. syyskuuta 2008

Yhteisöllisyys

Jo blogin ensimmäisessä (muistaakseni..) kirjoituksessa esitin yhdeksi tavoitteistani käynnistää jonkinlainen, vaikka edes suppea, yhteisöllinen lojban-toiminta. Jos ainakin aluksi kriteerit olisivat matalalla, niin kaikille lojbanista kiinnostuneille kevyestä yhteisöllisestä toiminnasta olisi enemmän iloa ja hyötyä kuin vaivaa. Vaivaa tulisi vasta sitten, kun perustettaisiin rekisteröity yhdistys pakollisine kokouksineen ja pöytäkirjoineen. Ja silloinkin kohtuullisesti.
Löysänkin yhteisöllisyyden yksi hyvä tavoite olisi järjestää esim kerran vuodessa yhteistapaaminen, joka sisältäisi lähinnä opetusta, workshoppeja ja vapaata keskustelua. Tiedän (runsaan kuukauden) Google-analyst seurannan tuloksena, että tätä blogia tarkkailee säännöllisesti 4-6 henkilöä ja on todennäköistä, että määrä kasvaa puolen vuoden kuluessa ehkä kaksinkertaiseksi. Tietysti tämä toteutuu sillä (minimi) edellytyksellä, että minä itse pystyn väsäämään uusia kirjoituksia tasaisin välein ja kirjoitukset sisältävät lisäksi riittävän kiinnostavia raportteja projektistani. Olettaisin ehtojen toteutuvan.

Itsekkäät tavoitteet? Oma itsekäs tavoitteeni saavuttaa sellainen asiantuntemus, että voisin sillä esim 3v kuluttua hankkia leipäni ja työllistää itseni eläkeikään asti (siis n. 7v ajan). Liiketoimintamallia ei vielä ole.

Epäitsekkäänä tavoitteena on tuoda "lojban-tietoisuutta" Suomeen. Koska, kuten olen aiemmin esittänyt, pidän lojbania erittäin hyödyllisenä työkaluna monien eri ongelmien ratkaisuissa. Yhteisöllisyys edistäisi tätä tavoitetta kvanttihypyn lailla. Oletan, että lojban työllistäisi monia muitakin.

Mutta yhteisöllisyyden toteutuminen edellyttää pieniä aloitteita muiltakin kuin minulta. Edes ihan pieniä.

torstai 18. syyskuuta 2008

Harjoitusmaailman XML-kuvaus

Sain vihdoin laadituksi kuvaksen alla esitetystä 20:stä lojban-bridistä:
http://www.freedrive.com/member/viewfolder/173153
XML-tiedosto on siis esitys lauseiden syntaktisesta rakenteesta. Vääntäessäni tiedostoa löysin paljon virheitä lojban-lauseista. Korjaan virheet. Olen varma, että virheitä on vielä kaikkialla, lojban-tasolla, XML-tasolla ja koko ajattelussani. Seuraavaksi (päivitettyäni virheelliset lauseet) ladattuani sekä suomenkieliset että lojbanikieliset tiedostot XML:n seuraksi, teen neljänneksi esitykseksi PEG-kieliopin (Parsing Expression Grammar), jonka pitäisi olla jälleen yhtäpitävä edellisten kanssa. Sen jälkeen olisin kai valmis alkamaan vääntämään C++-koodia, jonka tietysti myöskin pitäisi olla sopusoinnussa edellisten kanssa. Koodin siis pitäisi lojban-tekstistä PEG-kielioppia käyttäen pystyä työstämään valmiiksi vertailumalliksi väsätty XML-tiedosto. Sitten ensimmäinen vaihe on valmis.

lauantai 13. syyskuuta 2008

Kehollisuuden vaatimus

Tekoälykeskustelussa, eteenkin filosofisessa sellaisessa, on eräs aihealue, joka on tavalla tai toisella jatkuvasti ajankohtainen. Se on kysymys "kehollisuuden" (embodiment) tarpeellisuudesta. On eräs koulukunta, jonka mielestä vain robotiikka voi johtaa aitoon, vahvaan, yleiseen tekoälyyn (AGI), koska vain robotin sensomotorinen toiminta "maadoittaa" robotin sisäisen tietämysrakenteen reaaliseen maailmaan. Kehityskykyinen robotti havainnoi todellista ulkomaailmaa aisteillaan ja osallistuu siihen motorisilla kyvyillään esim liikkumalla, navigoimalla ja liikuttelemalla ulkoisia objekteja. Täten robotin sisäinen malli ulkomaailmasta kypsyy oppimalla vastaamaan todellisen maailman hienojakoista hierarkista rakennetta.

AGI-keskustelusivuilla käytiin n. viikko sitten tähän asetelmaan liittyvä keskustelu, joka pohjautui Pei Wangin edellä kuvattuun väitteeseen kriittisesti suhtautuvaan mielipidekirjoitukseen.
http://www.mail-archive.com/agi@v2.listbox.com/msg13298.html

Vaikka em. robotiikkaa puoltava väite on uskottava ja looginen, sen "vain" -sisältö on epäilyttänyt Pei Wangin lisäksi myös minua. Olen ehdottomasti samaa mieltä, että pelkästeen omaan sisäiseen maailmaansa nojaava järjestelmä on kehityskyvytön ja vakavasti rajoittunut. Kehittyvän järjestelmän on oltava interaktiivisessa suhteessa ulkomaailmaan. Mutta epäilen vahvasti sellaista ehdottomuutta, että vain robotin sensomotorinen suhde ulkomaailmaan olisi ainoa mahdollisuus tarjota AGI-tasoiseksi älyksi pyrkivälle järjestelmälle toiminta- ja kehityskentän.

Onhan robotinkin kokema maailma aina jotenkin rajoittunut. Sillä ei ole täydellisiä aisteja ja sen toimintaympäristö on mahdollisesta monipuolisuudestaan huolimatta aina pieni vain pieni osajoukko kaikesta kuviteltavissa olevasta. Miksi siis tällainen "robotin leikkikenttä" olisi ainoa mahdollinen kehittävä "leikkikenttä"? Voisin kuvitella muitakin mahdollisuuksia.

Kuten Pei Wang, minäkin olen pohdiskellut (jo vuosien ajan) mitä rajoituksia ja mahdollisuuksia olisi sellaisella AI-järjestelmällä, joka toimii pelkästään "ASCII-maailmassa" eli näppäimistöltä kirjoitettavissa olevien merkkien rajoittamassa todellisuudessa. Tällainen todellisuus olisi täysin erilainen kuin esim huonetiloissa operoivan, näkevän, kuulevan ja tuntevan (kosketusaistin kautta) humanoidirobotin maailma. Mutta olisiko ASCII-maailma liian suppea tai muuten huonompi?

Ben Goerzelin näkemyksen mukaan (em. keskustelu) tällainen "humanoidiaisteihin" ja motorisiin ulottuvuuksiin perustuva maailma tarjoaa hahmoja, joiden tilastolliset ominaisuudet eroavat radikaalisti edukseen, sopien paremmin esimerkiksi ihmislapsen tai muun kehittyvän mielen kehitysympäristöksi, kuin vaihtoehtona yksipuolisesti symbolinen maailma. Mutta hän itse myöntää, että hän ei voi todistaa väitettään vaan se perustuu puhtaasti intuitioon. Benin näkemys on ilmeisen totta, kun kysymys on biologisten aivojen oppimiskyvystä. Tämä siksi, että biologiset aivot ovat vuosimiljoonien kuluessa erikoistuneet juuri tällaiseen ympäristöön. Mutta entä jos aivojen perustana on tavallisten tietokoneiden "von-Neuman-arkkitehtuuri"? Minä ja Pei emme ole siinä tilanteessa varmoja tilanteesta. Ainakin näiden vaihtoehtoisten "leikkikenttien" laadullinen ero on kaventunut ja symboolimaailmalla on joitakin etujakin. Näitä etuja ovat ainakin sensomotorisen järjestelmäarkkitehtorisen kerroksen suhteellinen yksinkertaisuus ja laskentakapasiteetin pienempi tarve verrattuna audio-visuaaliseen aistidataan ja fyysisen maailman liikeballistiikan hallinnan vaatimuksiin.

Minun esimerkkini tekstibotin opettavaksi leikkikentäksi voisi olla C++ ohjelmointi. Maailma muodostuisi kausaalisesta "tuotantoketjusta": botin tuottama lähdekoodi - käännöstyökalut - debug-ympäristö - vaativampi testiympäristö - ohjelman tulosteet. Samoin kuin fyysisellä robotilla, myös tekstibotilla olisi ulkoa annetut toiminnat tavoitteet ja arvohierarkia. Molemmilla järjestelmillä olisi mahdollisuus muodostaa kausaalisen toiminnan kautta tuntemus oman "itsen" olemassaolosta ensimmäisenä vaiheena kohti "reflektiivistä itsetitetoisuutta" ja "vapaan tahdon kokemusta". Käännös- ja testiympäristö sekä "valvojan" (ihminen) liittymä muodostavat tekstibotin kausaalisen "ulkomaailman". Tällainen ympäristö tarjoaa ihmisohjelmoijalle kovatasoisia ja monipuolisia haasteita, niin miksei tekstibotillekin?

Pei Wangin mukaan kehollisuuden tärkeimmät kriteerit ovat, ei robotiikka, vaan se kokemus ja vuorovaikutteisuus, jota järjestelmä ulkomaailman suhteen harrastaa.

Mutta älköön kukaan kuvitelko, että minä tässä vaiheessa rakentelen mitään edelläkuvatun kaltaista. Olen lähempänä maanpintaa.

perjantai 5. syyskuuta 2008

Tarkennan hieman vaiheita

Tuon edellisen tekstin kommenttikirjoittelun pohjalta tarkennan hieman kahta ensimmäistä projektin vaihetta.

Ensimmäisen vaiheen tarkoitus on oikeastaan vain osata parsia lojban-kielinen lause kerrallaan. Lauseet riippuvat toisistaan vain selkeästi määriteltyjen prosumtien kautta, mutta lauseiden kokonaissemantiikkaa ei integroida. Tulostettavan XML-tiedoston ainoa tarkoitus on tässä vaiheessa vain olla verifiontia varten, että parsinta on tehty oikein. Tiedostoa ei ole tarkoitus käyttää mihinkään muuhun erityiseen, eikä esim lukea sisään uudestaan.

Toisen vaiheen tarkoitus on tuoda mukaan lauseiden yhteisen semanttisen sisällön integrointi. Semanttinen sisältö rakennetaan sisäiseksi olioesitystavaksi, joka vastaa tarkoin tulostettavaa XML-tiedoistoa. Tämä toisen vaiheen XML-tiedosto siis sisältää koko luetun tekstin kaikkien lauseiden ja mahdollisen pohjalla olevan semanttisen rakenteen yhteisen, integroidun kuvauksen. Tätä tiedostoa käytetään esinnäkin tallennettaessa tietämys levylle suljettaessa ohjelma ja ohjelman uudelleenkäynnistyksessä luettaessa vanha tietämys ajonaikaiseksi oliorakenteeksi.

Toinen erittäin mahdollinen käyttötapa on jokin muu hyötykäyttö, tiedosto on ohjelman tärkein tuloste. Tässä tulevat kyseeseen muut XML-työkalut.

Mutta muuten ohjelmalle ei ole tarkoitus syöttää mitään uutta XML-tietoa sen (tai sen muiden kopioiden) tallentamia tietämysrakennelmia lukuunottamatta. Uutta tietoa syötetään sisään vain "puhtaina lojban-lauseina", ei XML-muodossa.

Parserin on tarkoitus olla PEG-parseri. Syntaksi esiintyy lähinnä .h-tiedoston tasolla. Jokainen säännöistä on oma olionsa, joka alustetaan .h-tiedoston parametreilla.

maanantai 1. syyskuuta 2008

Softaprojekti alkaa

Oppikirjaprojekti on ollut puoliksi itselleni, lojbanin opiskelun runko, puoliksi tarkoitettu avuksi muille, suomenkielisille, lojbanista kiinnostuneille. Vaikka oppikirjan loppuun sattaminen jatkuukin, oletan olevani nyt valmis lojban-ohjelmani seuraavaan projektiin.
Nyt aion aloittaa pitkän hankkeen, jonka lopullisena tavoitteena on lojbaniksi interaktiivisesti kommunikoiva botti. Botti hallitsee laajan ontologian, ymmärtää ainakin lojban-kielen suurta osajoukkoa, ellei koko kieltä, osaa vastata järkevästi lojbankielisiin kysymyksiin sekä esittää omia kommentteja ja kysymyksiä esimerkiksi inkonsistenttisen tiedon suhteen. Botti ylläpitää laajaa tietämyskantaa, jota se keskustelun kuluessa kasvattaa ja päivittää.
Ei ole tässä vaiheessa tarpeen esittää yksityiskohtaista roadmappia ja aikataulua tavoitteeseen, mutta esittelen kolme ensimmäistä vaihetta.
  1. Parseri, jäsentelijä, joka osaa lukea rajoitettua syntaksia käyttävän lojban-kieleisen tekstitiedoston. Tiedosto kuvaa yksinkertaisen "harjoitusmaailman". Siis tiedoston kaikki lauseet liittyvät konsistentisti toisiinsa, täydentävät yhteistä verbaalista harjoitustodellisuuden kuvausta. Kukin lause erikseen parsitaan omaksi osakseen kokonaisutta esittäväksi XML-tedostoksi.
  2. Hieman laajempi harjoitusmaailma ja laajempi syntaktinen pelivara. Yksittäiset lauseet yhdisteään yhdeksi konsistententiksi harjoitusmaailman XML-kuvaukseksi. XML-kuvauksen takana on luonnollisesti ajonaikainen oliorakenne. Ohjelma osaa lukea sisään tallentamansa kuvauksen ja täydentää sitä lisälauseilla, joiden konsistenttisuus tarkastetaan.
  3. Lisätään vastauskyky yksinkertaisiin harjoitusmaailmaa koskeviin kysymyksiin.
Seuraavaksi esittelen ensimmäisen harjoitusmaailman. Se käsittää vain 20 lausetta.

Ensin suomeksi:

  1. Islalojbanis on meren ympäröimä saari.

  2. Meren nimi on Atlantis.

  3. Saari on muodostunut kalliosta.

  4. Saarella on metsää.

  5. Metsä on muodostunut puista.

  6. Ihmiset tulevat Islalojbanikselle mantereelta meren yli laivalla.

  7. Islalojbanikseksella asuu ihmisiä ja kaneja

  8. Meressä on kaloja.

  9. Saaren kanit syövät kasveja.

  10. Puut ja ruoho ovat kasveja, joita kanit syövät.

  11. Ihmiset syövät kasveja, kaloja ja kaneja.

  12. Ihmiset pyydystävät kaloja merestä ja kaneja saarelta.

  13. Ihmiset viljelevät kasveja, joita he syövät.

  14. Kasveja, joita ihmiset syövät, ovat peruna, riisi, olivi ja sipuli

  15. Ihmiset asuvat taloissa.

  16. Kanit asuvat koloissa.

  17. Mantereen ihmiset vierailevat Islalojbanikseksella ja Islalojbanikseksen ihmiset mantereella.

  18. Islalojbanis on kaunis, silloin kun sen metsät ovat vihreitä.

  19. Talvella metsät eivät ole vihreitä koska puiden lehdet putoavat.

  20. Kesällä meri on rauhallinen, mutta talvella meri on myrskyinen.




Sitten sama lojbaniksi:

ni'o la .islalojbanis. goi ko'i cu daplu fi le xamsi

.i la .atlantis. goi ko'a cu cmene le xamsi

.i ko'i rocki

.i ko'i vasru lei ricfoi

.i le ricfoi cu gunma lei tricu

.i loi remna cu klama ko'i le braplu mu'o ko'a le bloti

.i ko'i se xabju lo'i remna goi ko'e .e lo'i ractu goi fo'a

.i lo'i finpe cu nenri ko'a

.i fo'a pe ko'i cu citka le'i spati

.i le'i tricu .e le blaci cu cmima le'i spati poi se citka fo'a

.i ko'e cu citka le'i spati .e le'i finpe .e fo'a

.i ko'e se purdi fi lei spati poi lei ko'e cu citka ke'a

.i lo patlu .e lo rismi .e lo alzaidu .e lo sluni cu spati poi ko'e citka ko'e

.i ko'e xabju le zdani

.i fo'a xabju le kevna

.i le remna pe le braplu cu vitke ko'a .ije le remna pe ko'a cu vitke le braplu

.i ko'a melbi lenu lei ricfoi pe le daplu cu grino

.i lei ricfoi na cu crino lenu le dunra kei ri'a loi pezli pe loi trizu pu cu farlu

.i lenu le crisa fa le xamsi cu smaji ki'i ri to'e smaji lenu le dunra


Valitettavasti blogin asetukset sotkevat yrityksen lisätä tähän loppuun pätkä tavoitteena olevaa XML-koodia, jota minulla on valmiina. Mutta luonnollisesti laadin tavoite-XML-koodin valmiiksi ennenkuin kirjoitan riviääkään C++ -koodia.