Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss
Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Ada-Europe conference - 31 Jan Journal Track Extended Deadline

122 views
Skip to first unread message

Dirk Craeynest

unread,
Jan 8, 2024, 5:44:08 AM1/8/24
to
-----------------------------------------------------------------------

UPDATED Call for Contributions

28th Ada-Europe International Conference on
Reliable Software Technologies (AEiC 2024)

11-14 June 2024, Barcelona, Spain

www.ada-europe.org/conference2024

*** Journal track deadline EXTENDED to 31 January 2024 ***
*** Other submissions by 26 February 2024 ***

Organized by Ada-Europe
and Barcelona Supercomputing Center (BSC),
in cooperation with ACM SIGAda, ACM SIGBED, ACM SIGPLAN,
and Ada Resource Association (ARA)

#AEiC2024 #AdaEurope #AdaProgramming

-----------------------------------------------------------------------

*** General Information

The 28th Ada-Europe International Conference on Reliable Software
Technologies (AEiC 2024) will take place in Barcelona, Spain.

AEiC is a leading international forum for providers, practitioners,
and researchers in reliable software technologies. The conference
presentations will illustrate current work in the theory and practice
of the design, development, and maintenance of long-lived, high-quality
software systems for a challenging variety of application domains.
The program will also include keynotes, Q&A and discussion sessions,
and social events. Participants include practitioners and researchers
from industry, academia, and government organizations active in the
development of reliable software technologies.

The topics of interest for the conference include but are not limited
to (more specific topics are described on the conference web page):
* Formal and Model-Based Engineering of Critical Systems;
* High-Integrity Systems and Reliability;
* AI for High-Integrity Systems Engineering;
* Real-Time Systems;
* Ada Language;
* Applications in Relevant Domains.

The conference comprises different tracks and co-located events:
* Journal track papers present research advances supported by solid
theoretical foundation and thorough evaluation.
* Industrial track contributions highlight industrial open challenges
and/or the practitioners' side of a relevant case study or industrial
project.
* Work-in-progress track papers illustrate novel research ideas
that are still at an initial stage, between conception and first
prototype.
* Tutorials guide attenders through a hands-on familiarization with
innovative developments or with useful features related to reliable
software.
* Workshops provide discussion forums on themes related to the
conference topics.
* Vendor presentations and exhibitions allow for companies to showcase
their latest products and services.

*** Important Dates

31 January 2024 EXTENDED submission deadline for journal track papers
26 February 2024 Deadline for submission of industrial track papers,
work-in-progress papers, tutorial and workshop
proposals
22 March 2024 First round notification for journal track papers,
and notification of acceptance for all other types
of submissions
11-14 June 2024 Conference

*** Call for Journal Track Submissions

Following a journal-first model, this edition of the conference
includes a journal track, which seeks original and high-quality
papers that describe mature research work on the conference topics.
Accepted journal track papers will be published in a Special Issue
of Elsevier JSA - the Journal of Systems Architecture (Q1 ranked,
CiteScore 8.5, impact factor 4.5). Accordingly, the conference
is listed as "Journal Published" in the latest update of the CORE
Conference Ranking released in August 2023. Contributions must be
submitted by 31 January 2024. Submissions should be made online at
https://www.editorialmanager.com/jsa/, selecting the "Ada-Europe AEiC
2024" option (submission page open from 15 November 2023) as article
type of the paper. General information for submitting to the JSA
can be found at the Journal of Systems Architecture website.

JSA has adopted the Virtual Special Issue model to speed up the
publication process, where Special Issue papers are published in
regular issues, but marked as SI papers. Acceptance decisions
are made on a rolling basis. Therefore, authors are encouraged to
submit papers early, and need not wait until the submission deadline.
Authors who have successfully passed the first round of review will
be invited to present their work at the conference. The abstract of
the accepted contributions will be included in the conference booklet.

The Ada-Europe organization will waive the Open Access fees for
the first four accepted papers (whose authors do not already enjoy
Open Access agreements). Subsequent papers will follow JSA regular
publishing track. Prospective authors may direct all enquiries
regarding this track to the corresponding chairs, Bjorn Andersson
(baand...@sei.cmu.edu) and Luis Miguel Pinho (l...@isep.ipp.pt).

*** Call for Industrial Track Submissions

The conference seeks industrial practitioner presentations that deliver
insight on the challenges of developing reliable software. Especially
welcome kinds of submissions are listed on the conference website.
Given their applied nature, such contributions will be subject to a
dedicated practitioner-peer review process. Interested authors shall
submit a 1-to-2 pages abstract, by 26 February 2024, via EasyChair
at https://easychair.org/my/conference?conf=aeic2024, selecting the
"Industrial Track". The format for submission is strictly in PDF,
following the Ada User Journal style. Templates are available at
http://www.ada-europe.org/auj/guide.

The abstract of the accepted contributions will be included in the
conference booklet. The corresponding authors will get a presentation
slot in the prime-time technical program of the conference and will
also be invited to expand their contributions into full-fledged
articles for publication in the Ada User Journal, which will form the
proceedings of the industrial track of the Conference. Prospective
authors may direct all enquiries regarding this track to its chairs
Luciana Provenzano (luciana.p...@mdu.se) and Michael Pressler
(Michael....@de.bosch.com).

*** Call for Work-in-Progress Track Submissions

The work-in-progress track seeks two kinds of submissions: (a) ongoing
research and (b) early-stage ideas. Ongoing research submissions
are 4-page papers describing research results that are not mature
enough to be submitted to the journal track. Early-stage ideas are
1-page papers that pitch new research directions that fall within
the scope of the conference. Both kinds of submissions must be
original and shall undergo anonymous peer review. Submissions
by recent MSc graduates and PhD students are especially sought.
Authors shall submit their work by 26 February 2024, via EasyChair
at https://easychair.org/my/conference?conf=aeic2024, selecting the
"Work-in-Progress Track". The format for submission is strictly in
PDF, following the Ada User Journal style. Templates are available
at http://www.ada-europe.org/auj/guide.

The abstract of the accepted contributions will be included in the
conference booklet. The corresponding authors will get a presentation
slot in the prime-time technical program of the conference and
will also be offered the opportunity to expand their contributions
into 4-page articles for publication in the Ada User Journal,
which will form the proceedings of the WiP track of the Conference.
Prospective authors may direct all enquiries regarding this track
to the corresponding chairs Alejandro R. Mosteo (amo...@unizar.es)
and Ruben Martins (rub...@andrew.cmu.edu).

*** Awards

The organization will offer an honorary award for the best technical
presentation, to be announced in the closing session of the conference.

*** Call for Tutorials

The conference seeks tutorials in the form of educational seminars
on themes falling within the conference scope, with an academic or
practitioner slant, including hands-on or practical elements. Tutorial
proposals shall include a title, an abstract, a description of the
topic, an outline of the presentation, the proposed duration (half-day
or full-day), the intended level of the contents (introductory,
intermediate, or advanced), and a statement motivating attendance.
Tutorial proposals shall be submitted at any time but no later
than the 26 February 2024 to the respective chair Maria A. Serrano
(maria....@nearbycomputing.com), with subject line: "[AEiC 2024:
tutorial proposal]". Once submitted, each tutorial proposal will
be evaluated by the conference organizers as soon as possible,
with decisions from January 1st. The authors of accepted full-day
tutorials will receive a complimentary conference registration, halved
for half-day tutorials. The Ada User Journal will offer space for
the publication of summaries of the accepted tutorials.

*** Call for Workshops

The conference welcomes satellite workshops centred on themes that fall
within the conference scope. Proposals may be submitted for half- or
full-day events, to be scheduled at either end of the AEiC conference.
Workshop organizers shall also commit to producing the proceedings of
the event, for publication in the Ada User Journal. Workshop proposals
shall be submitted at any time but no later than the 26 February
2024 to the respective chair Sergio Saez (ss...@disca.upv.es), with
subject line: "[AEiC 2024: workshop proposal]". Once submitted, each
workshop proposal will be evaluated by the conference organizers as
soon as possible, with decisions from January 1st.

*** Academic Listing

The Journal of Systems Architecture, publication venue of the journal
track proceedings of the conference, is Q1 ranked, with CiteScore
8.5 and Impact Factor 4.5. The Ada User Journal, venue of all other
technical proceedings of the conference, is indexed by Scopus and by
EBSCOhost in the Academic Search Ultimate database.

*** Call for Exhibitors and Sponsors

The conference will include a vendor and technology exhibition with the
option of a 20 minutes presentation as part of the conference program.
Interested providers should direct inquiries to the Exhibition &
Sponsorship Chair Ahlan Marriot (ah...@ada-switzerland.ch).

*** Venue

The conference will take place in Barcelona, Spain. Barcelona is
a major cultural, economic, and financial centre, known for its
architecture, culture, and Mediterranean atmosphere, a hub for
technology and innovation. There's plenty to see and visit in
Barcelona, so plan in advance!

*** Organizing Committee

- Conference Chair
Sara Royuela, Barcelona Supercomputing Center, Spain
sara.r...@bsc.es

- Journal Track Chairs
Bjorn Andersson, Carnegie Mellon University, USA
baand...@sei.cmu.edu
Luis Miguel Pinho, ISEP & INESC TEC, Portugal
l...@isep.ipp.pt

- Industrial Track Chairs
Luciana Provenzano, Mälardalen University, Sweden
luciana.p...@mdu.se
Michael Pressler, Robert Bosch GmbH, Germany
Michael....@de.bosch.com

- Work-In-Progress Track Chairs
Alejandro R. Mosteo, CUD Zaragoza, Spain
amo...@unizar.es
Ruben Martins, Carnegie Mellon University, USA
rub...@andrew.cmu.edu

- Tutorial Chair
Maria A. Serrano, NearbyComputing, Spain
maria....@nearbycomputing.com

- Workshop Chair
Sergio Saez, Universitat Politècnica de València, Spain
ss...@disca.upv.es

- Exhibition & Sponsorship Chair
Ahlan Marriott, White Elephant GmbH, Switzerland
ah...@Ada-Switzerland.ch

- Publicity Chair
Dirk Craeynest, Ada-Belgium & KU Leuven, Belgium
Dirk.Cr...@cs.kuleuven.be

- Webmaster
Hai Nam Tran, University of Brest, France
hai-na...@univ-brest.fr

- Local Chair
Nuria Sirvent, Barcelona Supercomputing Center, Spain
nuria....@bsc.es

*** Journal Track Committee

Al Mok, University of Texas at Austin, USA
Alejandro Mosteo, CUD Zaragoza, Spain
Alwyn Godloe, NASA, USA
António Casimiro, University of Lisbon, Portugal
Barbara Gallina, Mälardalen University, Sweden
Bernd Burgstaller, Yonsei University, South Korea
C. Michael Holloway, NASA, USA
Cristina Seceleanu, Mälardalen University, Sweden
Doug Schmidt, Vanderbilt University, USA
Frank Singhoff, University of Brest, FR
George Lima, Universidade Federal da Bahia, Brazil
Isaac Amundson, Rockwell Collins, USA
Jérôme Hugues, CMU/SEI, USA
José Cruz, Lockeed Martin, USA
Kristoffer Nyborg Gregertsen, SINTEF Digital, Norway
Laurent Pautet, Telecom ParisTech, France
Leonidas Kosmidis, Barcelona Supercomputing Center, Spain
Mario Aldea Rivas, University of Cantabria, Spain
Matthias Becker, KTH - Royal Institute of Technology, Sweden
Patricia López Martínez, University of Cantabria, Spain
Sara Royuela, Barcelona Supercomputing Center, Spain
Sergio Sáez, Universitat Politècnica de València, Spain
Tucker Taft, AdaCore, USA
Tullio Vardanega, University of Padua, Italy
Xiaotian Dai, University of York, England

*** Industrial Track Committee

Aida Causevic, Alstom, Sweden
Alexander Viehl, Research Center for Information Technology, Germany
Ana Rodríguez, Silver Atena, Spain
Aurora Agar, NATO, Netherlands
Behnaz Pourmohseni, Robert Bosch GmbH, Germany
Claire Dross, AdaCore, France
Elena Lisova, Volvo CE, Sweden
Enricco Mezzeti, Barcelona Supercomputing Center, Spain
Federico Aromolo, Scuola Superiore Sant'Anna, Italy
Helder Silva, Edisoft, Portugal
Hugo Torres Vieira, Evidence Srl, Italy
Irune Agirre, Ikerlan, Spain
Jordi Cardona, Rapita Systems, Spain
José Ruiz, AdaCore, France
Joyce Tokar, Raytheon, USA
Luciana Alvite, Alstom, Germany
Marco Panunzio, Thales Alenia Space, France
Patricia Balbastre Betoret, Valencia Polytechnic University, Spain
Philippe Waroquiers, Eurocontrol NMD, Belgium
Raúl de la Cruz, Collins Aerospace, Ireland
Santiago Urueña, GMV, Spain
Stef Van Vlierberghe, Eurocontrol NMD, Belgium

*** Work-in-Progress Track Committee

Alan Oliveira, University of Lisbon, Portugal
J. Javier Gutiérrez, University of Cantabria, Spain
Jérémie Guiochet, LAAS-CNRS, France
Kalinka Branco, University of São Paulo, Brazil
Katherine Kosaian, University of Iowa, USA
Kevin Cheang, AWS, USA
Kristin Yvonne Rozier, Iowa State University, USA
Leandro Buss Becker, University of Manchester, UK
Li-Pin Chang, National Yang Ming Chiao Tung University, Taiwan
Mathias Preiner, Stanford University, USA
Raffaele Romagnoli, Carnegie Mellon University, USA
Robert Kaiser, RheinMain University of Applied Sciences, Germany
Sara Abbaspour, Mälardalen University, Sweden
Sergi Alcaide, Barcelona Supercomputing Center, Spain
Simona Bernardi, Unizar, Spain
Stefan Mitsch, School of Computing at DePaul University, USA
Teresa Lázaro, Aragon's Institute of Technology, Spain
Tiago Carvalho, ISEP, Portugal
Yannick Moy, AdaCore, France

*** Previous Editions

Ada-Europe organizes annual international conferences since the early
80's. This is the 28th event in the Reliable Software Technologies
series, previous ones being held at Montreux, Switzerland ('96),
London, UK ('97), Uppsala, Sweden ('98), Santander, Spain ('99),
Potsdam, Germany ('00), Leuven, Belgium ('01), Vienna, Austria
('02), Toulouse, France ('03), Palma de Mallorca, Spain ('04), York,
UK ('05), Porto, Portugal ('06), Geneva, Switzerland ('07), Venice,
Italy ('08), Brest, France ('09), Valencia, Spain ('10), Edinburgh, UK
('11), Stockholm, Sweden ('12), Berlin, Germany ('13), Paris, France
('14), Madrid, Spain ('15), Pisa, Italy ('16), Vienna, Austria ('17),
Lisbon, Portugal ('18), Warsaw, Poland ('19), online from Santander,
Spain ('21), Ghent, Belgium ('22), and Lisbon, Portugal ('23).

Information on previous editions of the conference can be found at
www.ada-europe.org/confs/ae.

-----------------------------------------------------------------------

Our apologies if you receive multiple copies of this announcement.
Please circulate widely.

Dirk Craeynest, AEiC 2024 Publicity Chair
Dirk.Cr...@cs.kuleuven.be

* 28th Ada-Europe Int. Conf. Reliable Software Technologies (AEiC 2024)
* June 11-14, 2024, Barcelona, Spain, www.ada-europe.org/conference2024

(V4.4)

Patricia Ferreira

unread,
Jan 8, 2024, 11:05:36 AM1/8/24
to
di...@orka.cs.kuleuven.be. (Dirk Craeynest) writes:

> *** General Information
>
> The 28th Ada-Europe International Conference on Reliable Software
> Technologies (AEiC 2024) will take place in Barcelona, Spain.
>
> AEiC is a leading international forum for providers, practitioners,
> and researchers in reliable software technologies. The conference
> presentations will illustrate current work in the theory and practice
> of the design, development, and maintenance of long-lived, high-quality
> software systems for a challenging variety of application domains.

/Long-lived high-quality software systems/. É interessante que existam
conferências inteiras especializadas numa linguagem de programação só.
/Long-lived high-quality software systems/ em Ada.

Também é legal ver como muitos sistemas de alta qualidade não são
escritos nas linguagens mais populares que existem por aí.

Dirk Craeynest

unread,
Jan 9, 2024, 4:53:27 AM1/9/24
to
>di...@orka.cs.kuleuven.be. (Dirk Craeynest) writes:
>> AEiC is a leading international forum for providers, practitioners,
>> and researchers in reliable software technologies. The conference
>> presentations will illustrate current work in the theory and practice
>> of the design, development, and maintenance of long-lived, high-quality
>> software systems for a challenging variety of application domains.

Patricia Ferreira <pfer...@example.com> wrote:
= /Long-lived high-quality software systems/. É interessante que
= existam conferências inteiras especializadas numa linguagem de
= programação só. /Long-lived high-quality software systems/ em Ada.

[Desculpe por não responder em português.]

Note that, while the Ada programming language and technology is an
important topic at the Ada-Europe conference series on *reliable
software technologies*, it is not the only topic (see Call for
Contributions).

= Também é legal ver como muitos sistemas de alta qualidade não são
= escritos nas linguagens mais populares que existem por aí.

Ada might not be the most popular language out there, but definitely
is a very suitable one to develop long-lived high-quality software
systems. Been there, done that... ;-)

Dirk

Patricia Ferreira

unread,
Jan 9, 2024, 7:31:21 AM1/9/24
to
di...@orka.cs.kuleuven.be. (Dirk Craeynest) writes:

>>di...@orka.cs.kuleuven.be. (Dirk Craeynest) writes:
>>> AEiC is a leading international forum for providers, practitioners,
>>> and researchers in reliable software technologies. The conference
>>> presentations will illustrate current work in the theory and practice
>>> of the design, development, and maintenance of long-lived, high-quality
>>> software systems for a challenging variety of application domains.
>
> Patricia Ferreira <pfer...@example.com> wrote:
> = /Long-lived high-quality software systems/. É interessante que
> = existam conferências inteiras especializadas numa linguagem de
> = programação só. /Long-lived high-quality software systems/ em Ada.
>
> [Desculpe por não responder em português.]

That's alright. (I bet most of us speak English too.)

> Note that, while the Ada programming language and technology is an
> important topic at the Ada-Europe conference series on *reliable
> software technologies*, it is not the only topic (see Call for
> Contributions).

Because Ada is in the name of conference, I assume it's always Ada we're
talking about that when I read the paragraph below. (So, thanks for
clarifying.)

--8<---------------cut here---------------start------------->8---
AEiC is a leading international forum for providers, practitioners,
and researchers in reliable software technologies. The conference
presentations will illustrate current work in the theory and practice
of the design, development, and maintenance of long-lived, high-quality
software systems for a challenging variety of application domains.
The program will also include keynotes, Q&A and discussion sessions,
and social events. Participants include practitioners and researchers
from industry, academia, and government organizations active in the
development of reliable software technologies.
--8<---------------cut here---------------end--------------->8---

> = Também é legal ver como muitos sistemas de alta qualidade não são
> = escritos nas linguagens mais populares que existem por aí.
>
> Ada might not be the most popular language out there, but definitely
> is a very suitable one to develop long-lived high-quality software
> systems. Been there, done that... ;-)

I applaude that! Programming seems to be a field that it's very hard to
educate oneself. For instance, I never gave myself an introduction to
Ada. Like most of everyone I assumed it was some relic. I just visited

https://ada-lang.io/

for the first time and I was happy to see the website.

But not all is blues in my life. Not too late in my life I found Lisp
and I was very surprised to realize how interesting it is and how
ignored it is by the vast percentage of programmers.

I would be so happy to be able to submit a contribution to AEiC, but it
would be much more likely that I would do it for a Lisp conference. :-)

Daniel Cerqueira

unread,
Jan 10, 2024, 8:18:40 AM1/10/24
to
Patricia Ferreira <pfer...@example.com> writes:

> But not all is blues in my life. Not too late in my life I found Lisp
> and I was very surprised to realize how interesting it is and how
> ignored it is by the vast percentage of programmers.
>
> I would be so happy to be able to submit a contribution to AEiC, but it
> would be much more likely that I would do it for a Lisp conference. :-)

Também descobri Lisp tarde, na minha vida professional de programador,
e, bem.... parece que o meu cérebro foi libertado da dor que é o C. Só
tenho prazer a programar em Lisp.

Estou a ler um livro que pensei que tinha perdido (longa história) que é
o Practical Common Lisp. Eu sei que há a versão online, mas após ter
comprado no formato físico, e o ter (pensado ter) perdido, deixei de dar
a continuidade da leitura com o online. Agora voltei, pois encontrei de
novo o livro :-)

Patrícia, quais livros de Lisp leste, e quais recomendas? Que tipo de
Lisp fala esses livros?

Sente-te à vontade de começar uma nova conversa neste grupo. Talvez isto
seja melhor.

Ninguém

unread,
Jan 10, 2024, 10:18:38 AM1/10/24
to
On 10/01/24 13:18, Daniel Cerqueira wrote:
> Patrícia, quais livros de Lisp leste, e quais recomendas? Que tipo de
> Lisp fala esses livros?

Também estou interessado.
Tento usar emacs, mas sem ser programador e não pescando nada de lisp,
fica difícil. Limito-me a aproveitar algumas funções mais fáceis de
entender - é como usar uma bazuca para matar moscas.

Nuno Silva

unread,
Jan 10, 2024, 10:59:40 AM1/10/24
to
Embora já conhecesse C, eu travei conhecimento digamos que "bem cedo"
(isto é, antes de aprender e/ou trabalhar com muitas outras linguagens)
com a família Lisp, neste caso R5RS (portanto Scheme).

Sei que a dada altura li o SICP e penso que o "ANSI Common Lisp" (se não
foi esse, a capa pelo menos parece semelhante, e tenho a certeza de que
incluía um exemplo com ray-tracing).

Penso que terei lido também (parcialmente?) outro livro, que me sugeriram
pouco antes de começar a utilizar R5RS, terá sido o HtDP?

Se algum de vocês anda pelos lados do "fediverso", sugiro esta conta
para alguns posts interessantes sobre Lisp:
http://fosstodon.org/@amoroso

(Com sorte, para receber esses posts bastaria seguir a hashtag #Lisp mas
isso depende da federação, tal como aliás se discutiu recentemente no
pt.internet.www.)

--
Nuno Silva

Patricia Ferreira

unread,
Jan 10, 2024, 2:37:18 PM1/10/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> But not all is blues in my life. Not too late in my life I found Lisp
>> and I was very surprised to realize how interesting it is and how
>> ignored it is by the vast percentage of programmers.
>>
>> I would be so happy to be able to submit a contribution to AEiC, but it
>> would be much more likely that I would do it for a Lisp conference. :-)
>
> Também descobri Lisp tarde, na minha vida professional de programador,
> e, bem.... parece que o meu cérebro foi libertado da dor que é o C. Só
> tenho prazer a programar em Lisp.

Que bom! E que bom que você conhece C também.

> Estou a ler um livro que pensei que tinha perdido (longa história)

Lol.

> que é o Practical Common Lisp. Eu sei que há a versão online, mas após
> ter comprado no formato físico, e o ter (pensado ter) perdido, deixei
> de dar a continuidade da leitura com o online. Agora voltei, pois
> encontrei de novo o livro :-)

Sempre melhor ter o livros em mãos.

> Patrícia, quais livros de Lisp leste, e quais recomendas? Que tipo de
> Lisp fala esses livros?

Os livros de Lisp que realmente li foram o HtDP e o SICP. Tem muita
coisa a se conversar aí. O Practical Common Lisp vai te apresentar um
jeito Common Lisp de escrever, mas é preciso saber se você já tem um
pouco do jeito Lisp de pensar --- antes do jeito Common Lisp. Você tem
sentido alguma dificuldade em algum lugar que você consiga descrever? A
gente começa a conversa por aí.

Estou iniciando com Common Lisp --- descobri esses dias. Não sabia que
era tão divertido usar Common Lisp. São poucos dias ainda, mas a gente
sabe o que gosta quando vê. É /absolutamente/ a melhor experiência que
já tive. Uso o GNU EMACS há muitos anos. Agora estou usando SLIME e
SBCL. Estou me divertindo *muito mais* com SBCL e SLIME do que com
Racket e racket-mode. Muito mais. As mensagens de erro do SBCL são
maravilhosas comparadas às mensagens de erro de Racket.

Patricia Ferreira

unread,
Jan 10, 2024, 2:57:23 PM1/10/24
to
O GNU EMACS é um software difícil de usar. Pra valer a pena o uso dele,
a gente faz um monte de customizações ao longo dos anos. O próprio uso
do GNU EMACS nos convida a conhecer Lisp e a vida no GNU EMACS sem Lisp
certamente não é a mais fácil. Por outro lado... O que mais tem por aí?
Tenho certeza que VSCode oferece um ambiente Lisp, mas não sei usar
aquilo e nem quero saber --- o GNU EMACS funciona muito bem pra quem
investiu bastante no uso dele.

Racket é uma escola completa. O DrRacket é fácil de instalar e usar.
Sem mistério. O HtDP é um livro pra iniciantes com profundas mensagens
e assume que você usará o DrRacket.

O SICP não é um livro que deve ser lido sem o leitor dominar as ideias
centrais do HtDP, por exemplo.

Agora, observe que em mensagem anterior eu disse que ter começado com
Racket foi minha pior decisão. Entender Racket não me parece fácil.
Tudo com Racket vai muito bem enquanto você está lendo o HtDP. O
problema é quando você resolve usar a linguagem de fato mesmo. Aí você
precisa ler a documentação, entender as coisas. É um outro mundo
completo a desbravar. Teria me dado muito melhor com Common Lisp.
Finalmente descobri isso.

Patricia Ferreira

unread,
Jan 10, 2024, 3:01:00 PM1/10/24
to
É o ANSI Common Lisp sim.

> Penso que terei lido também (parcialmente?) outro livro, que me sugeriram
> pouco antes de começar a utilizar R5RS, terá sido o HtDP?

Se fosse o HtDP, você lembraria.

> Se algum de vocês anda pelos lados do "fediverso", sugiro esta conta
> para alguns posts interessantes sobre Lisp:
> http://fosstodon.org/@amoroso

O Paolo Amoroso anda pelo comp.lang.lisp atualmente.

Daniel Cerqueira

unread,
Jan 11, 2024, 11:30:07 AM1/11/24
to
Patricia Ferreira <pfer...@example.com> writes:

> O Paolo Amoroso anda pelo comp.lang.lisp atualmente.

Sim, tenho visto bastante atividade do Amoroso em comp.lang.lisp ;-)

Daniel Cerqueira

unread,
Jan 11, 2024, 11:42:04 AM1/11/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Ninguém <use...@rasparta.org> writes:
>
>> On 10/01/24 13:18, Daniel Cerqueira wrote:
>>> Patrícia, quais livros de Lisp leste, e quais recomendas? Que tipo de
>>> Lisp fala esses livros?
>>
>> Também estou interessado.
>> Tento usar emacs, mas sem ser programador e não pescando nada de lisp,
>> fica difícil. Limito-me a aproveitar algumas funções mais fáceis de
>> entender - é como usar uma bazuca para matar moscas.
>
> O GNU EMACS é um software difícil de usar. Pra valer a pena o uso dele,
> a gente faz um monte de customizações ao longo dos anos. O próprio uso
> do GNU EMACS nos convida a conhecer Lisp e a vida no GNU EMACS sem Lisp
> certamente não é a mais fácil. Por outro lado... O que mais tem por aí?
> Tenho certeza que VSCode oferece um ambiente Lisp, mas não sei usar
> aquilo e nem quero saber --- o GNU EMACS funciona muito bem pra quem
> investiu bastante no uso dele.

Acho que chamar o GNU Emacs de difícil é uma má descrição.
Eu vejo desta maneira: Dá para expandir bastante o conhecimento do GNU
Emacs. Também dá para usá-lo de maneira simples.

O melhor a fazer é pegar numa configuração de Emacs (um .emacs ou
init.el) que anda nos resultados do teu motor de busca web favorito, e
aproveitar o que precisas. A partir de aí, vais construindo as tuas
configurações do GNU Emacs, com o passar dos dias, meses, anos.

Eu comecei a usar Emacs sem saber algo de Lisp, e consegui.

As minhas configurações de Emacs estão aqui:
https://danisanti.tilde.institute/files/emacs

Daniel Cerqueira

unread,
Jan 11, 2024, 12:04:03 PM1/11/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Que bom! E que bom que você conhece C também.

Sim, aprendi na Universidade do Minho. Infelizmente zero Lisp no curso
de Engenharia Informática. Apenas Haskell.

>> Estou a ler um livro que pensei que tinha perdido (longa história)
>
> Lol.
>
>> que é o Practical Common Lisp. Eu sei que há a versão online, mas após
>> ter comprado no formato físico, e o ter (pensado ter) perdido, deixei
>> de dar a continuidade da leitura com o online. Agora voltei, pois
>> encontrei de novo o livro :-)
>
> Sempre melhor ter o livros em mãos.
>

Comprei o livro, por estar em preço de promoção, e andava do olho nele
porque achei muito fixe o autor libertar o livro em formato online,
gratuitamente. Mereceu o meu dinheiro escasso.

>> Patrícia, quais livros de Lisp leste, e quais recomendas? Que tipo de
>> Lisp fala esses livros?
>
> Os livros de Lisp que realmente li foram o HtDP e o SICP. Tem muita
> coisa a se conversar aí. O Practical Common Lisp vai te apresentar um
> jeito Common Lisp de escrever, mas é preciso saber se você já tem um
> pouco do jeito Lisp de pensar --- antes do jeito Common Lisp. Você tem
> sentido alguma dificuldade em algum lugar que você consiga descrever? A
> gente começa a conversa por aí.

A dificuldade que tenho é apenas em decorar as várias funções/macros da
linguagem. Fora isso tenho andado bem, a passo lento, com tempo para
assimilação.

> Estou iniciando com Common Lisp --- descobri esses dias. Não sabia que
> era tão divertido usar Common Lisp. São poucos dias ainda, mas a gente
> sabe o que gosta quando vê. É /absolutamente/ a melhor experiência que
> já tive. Uso o GNU EMACS há muitos anos. Agora estou usando SLIME e
> SBCL. Estou me divertindo *muito mais* com SBCL e SLIME do que com
> Racket e racket-mode. Muito mais. As mensagens de erro do SBCL são
> maravilhosas comparadas às mensagens de erro de Racket.

Que bom que também partilhas este prazer. Escrever Common Lisp é
maravilhoso. Principalmente com o GNU Emacs.

Eu não uso SLIME porque não dá para criar imagens lisp com o SLIME. Uso
M-x run-lisp , e assim já consigo usar o save-lisp-and-die. Tenho uma
atitute minimalista com o software, uso apenas aquilo que realmente
preciso, tento não usar dois softwares que fazem a mesma coisa.

Também uso o SBCL.

Patricia, eu li e recomendo ler, os livros do John McCarthy sobre Lisp.

Que personagem. Dá para ver nos livros dele que ele era uma pessoa
brilhante. São simples e fácil de entender. Quem lê, fica a saber a
raíz por onde começou. Que é a melhor maneira de adquirir conhecimento.

Um dos seus websites é: http://www-formal.stanford.edu/jmc/

Ninguém

unread,
Jan 11, 2024, 5:21:37 PM1/11/24
to
Daniel Cerqueira (dan....@brilhante.top) escreveu no dia 2024-01-11
(Thursday), cerca das 16:42 +0000:
> Acho que chamar o GNU Emacs de difícil é uma má descrição.
> Eu vejo desta maneira: Dá para expandir bastante o conhecimento do
> GNU
> Emacs. Também dá para usá-lo de maneira simples.

Hehe!
Uso de maneira simples, então.

> O melhor a fazer é pegar numa configuração de Emacs (um .emacs ou
> init.el) que anda nos resultados do teu motor de busca web favorito,
> e
> aproveitar o que precisas. A partir de aí, vais construindo as tuas
> configurações do GNU Emacs, com o passar dos dias, meses, anos.

Eu entendo essa filosofia até certo ponto. Faço isso com o bash porque
já tenho algum conhecimento de bash, mas tenho dificuldade em utilizar
essa metodologia quando não entendo o que estou a fazer. Sinto-me um
bocado feiticeiro de Oz.
Não entendendo lisp, por exemplo, colocar uma data de "tralha que não
sei o que faz só porque tem o efeito que eu pretendo" no ficheiro de
configuração pode resolver-me o problema de utilização, mas não o de
ignorância.
Acho que a metodologia que a Patrícia sempre sugere talvez seja melhor
- ler um bom livro sobre o assunto - pelo menos até entender o mínimo
para ser perigoso, depois então, ok, ir arriscando um bocadinho.
Há pouco tempo dei com um artigo com o título semelhante a "emacs from
scratch". Pareceu-me adequado ao que pretendo, mas começa logo por me
pedir para confiar nas "magias" que o autor sugere à partida!...
desiludiu-me um bocado.

> Eu comecei a usar Emacs sem saber algo de Lisp, e consegui.
>
> As minhas configurações de Emacs estão aqui:
> https://danisanti.tilde.institute/files/emacs

"Bookmarkado" ;-)

Patricia Ferreira

unread,
Jan 12, 2024, 9:02:13 AM1/12/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Ninguém <use...@rasparta.org> writes:
>>
>>> On 10/01/24 13:18, Daniel Cerqueira wrote:
>>>> Patrícia, quais livros de Lisp leste, e quais recomendas? Que tipo de
>>>> Lisp fala esses livros?
>>>
>>> Também estou interessado.
>>> Tento usar emacs, mas sem ser programador e não pescando nada de lisp,
>>> fica difícil. Limito-me a aproveitar algumas funções mais fáceis de
>>> entender - é como usar uma bazuca para matar moscas.
>>
>> O GNU EMACS é um software difícil de usar. Pra valer a pena o uso dele,
>> a gente faz um monte de customizações ao longo dos anos. O próprio uso
>> do GNU EMACS nos convida a conhecer Lisp e a vida no GNU EMACS sem Lisp
>> certamente não é a mais fácil. Por outro lado... O que mais tem por aí?
>> Tenho certeza que VSCode oferece um ambiente Lisp, mas não sei usar
>> aquilo e nem quero saber --- o GNU EMACS funciona muito bem pra quem
>> investiu bastante no uso dele.
>
> Acho que chamar o GNU Emacs de difícil é uma má descrição.
> Eu vejo desta maneira: Dá para expandir bastante o conhecimento do GNU
> Emacs. Também dá para usá-lo de maneira simples.

Meu ponto de vista é a de um usuário mediano. Se eu o achasse realmente
difícil de usar, não o usaria. Se você for um programador e
especialmente se for um programador Lisp, o GNU EMACS é maravilhoso ou
quase isso. Se o uso for simples, talvez não haja no GNU EMACS nada que
realmente valha a pena.

Quando uma coisa é difícil de usar, é interessante entender por quê. Às
vezes a razão é simplesmente mal-projeto e aí a gente joga aquilo fora.
Tipicamente a gente consegue fazer a distinção por observar outras
pessoas usando. Se você observar alguns estudiosos do GNU EMACS
usando-o, você vê que o que parecia difícil é na verdade muito fácil
(pra eles). Então talvez não seja mal-projeto, mas uma ferramenta que
/você/ não compreenda.

De uma forma geral, uma abordagem interessante pra compreender /qualquer
coisa/ é compreender sua história. O GNU EMACS tem uma longa, longa
história. O nome EMACS já era usado por outros editores antes do GNU
EMACS. EMACS deriva-se de ``[e]ditor of [mac]ro[s]''. Em programação,
``macros'' representa a ideia de procedimentos que um compilador executa
(e não que seu programa executa). Só isso já sugere que EMACS tinha em
mente programadores LISP, o que sugere por sua vez que compreender LISP
seja útil pra compreender o próprio EMACS e sua história. Muitos
editores EMACS foram escritos. (Por exemplo, James Gosling, além de
Java, também escreveu um EMACS, chamado ``gosmacs''.)

Por que o GNU EMACS se minimiza quando se diz C-z? Porque está próximo
do efeito de se interromper o processo que está em primeiro plano no seu
terminal. Por que o GNU EMACS não ``se moderniza'' e se comporta como
programas Microsoft Windows? Primeiro porque o uso da palavra
``moderno'' não está muito adequada ao contexto; segundo porque o GNU
EMACS tem uma história muito mais longa que o Microsoft Windows. A
resposta curta pra essa pergunta é --- ``thanks, but no, thanks''. É
claro que o GNU EMACS poderia se comportar exatamente como um programa
Windows, mas não /se deseja isso/.

E aí começa a compreensão do porquê o GNU EMACS é tão difícil de usar
--- é porque você não tem essa cultura. Se você gosta do GNU EMACS e
deseja ter a habilidade de usá-lo, você precisa adquirir essa cultura.
Tem essa cultura quem sabe usar o GNU EMACS com eficácia.

Compreender a configuração de um GNU EMACS e compreender a documentação
vai ficar muito mais óbvia se você tiver um mínimo de linguagens Lisp.
Se seu objetivo é mais o GNU EMACS do que qualquer Lisp, então dê a si
mesmo um curso de ELISP.

Só comecei a entender o GNU EMACS depois de ler

An Introduction to Programming in Emacs Lisp
Robert J. Chassell, GNU Press, ISBN 1-882114-43-4

--8<---------------cut here---------------start------------->8---
This is ‘An Introduction to Programming in Emacs Lisp’, for people who
are not programmers.
--8<---------------cut here---------------end--------------->8---

Você encontra o livro no próprio GNU EMACS dizendo

Help -> More manuals -> Introduction to Emacs Lisp

ao seu GNU EMACS.

Daniel Cerqueira

unread,
Jan 12, 2024, 9:23:41 AM1/12/24
to
Ninguém <use...@rasparta.org> writes:

> Daniel Cerqueira (dan....@brilhante.top) escreveu no dia 2024-01-11
> (Thursday), cerca das 16:42 +0000:
>
> Não entendendo lisp, por exemplo, colocar uma data de "tralha que não
> sei o que faz só porque tem o efeito que eu pretendo" no ficheiro de
> configuração pode resolver-me o problema de utilização, mas não o de
> ignorância.
> Acho que a metodologia que a Patrícia sempre sugere talvez seja melhor
> - ler um bom livro sobre o assunto - pelo menos até entender o mínimo
> para ser perigoso, depois então, ok, ir arriscando um bocadinho.

Apoio essa metodologia. Eu também sou assim.

Uma ótima coisa no Emacs, é que podes aprender sobre o Emacs usando o
Emacs. Bootstrapping knowleadge :-) Por exemplo, tens o tutorial do
Emacs dentro do Emacs. Podes aceder ao tutorial usando C-h t (isto é,
Control pressionada mais a tecla h, largar o Control e carregar na tecla
t). Também tens o C-h C-h (isto é, Control pressionado e duas vezes a
tecla h) que é como obténs ajuda sobre a ajuda do Emacs.

> Há pouco tempo dei com um artigo com o título semelhante a "emacs from
> scratch". Pareceu-me adequado ao que pretendo, mas começa logo por me
> pedir para confiar nas "magias" que o autor sugere à partida!...
> desiludiu-me um bocado.

Espero que encontres algo melhor ;-) Se sabes usar o info do GNU, tens
vários livros info sobre Emacs e Emacs Lisp instalados no teu sistema.
Podes aceder ao info dentro do Emacs com C-h i

Patricia Ferreira

unread,
Jan 12, 2024, 9:24:48 AM1/12/24
to
Ninguém <use...@rasparta.org> writes:

> Daniel Cerqueira (dan....@brilhante.top) escreveu no dia 2024-01-11
> (Thursday), cerca das 16:42 +0000:

[...]

>> O melhor a fazer é pegar numa configuração de Emacs (um .emacs ou
>> init.el) que anda nos resultados do teu motor de busca web favorito,
>> e aproveitar o que precisas. A partir de aí, vais construindo as tuas
>> configurações do GNU Emacs, com o passar dos dias, meses, anos.
>
> Eu entendo essa filosofia até certo ponto. Faço isso com o bash porque
> já tenho algum conhecimento de bash, mas tenho dificuldade em utilizar
> essa metodologia quando não entendo o que estou a fazer. Sinto-me um
> bocado feiticeiro de Oz.
> Não entendendo lisp, por exemplo, colocar uma data de "tralha que não
> sei o que faz só porque tem o efeito que eu pretendo" no ficheiro de
> configuração pode resolver-me o problema de utilização, mas não o de
> ignorância.
> Acho que a metodologia que a Patrícia sempre sugere talvez seja melhor
> - ler um bom livro sobre o assunto - pelo menos até entender o mínimo
> para ser perigoso, depois então, ok, ir arriscando um bocadinho.
> Há pouco tempo dei com um artigo com o título semelhante a "emacs from
> scratch". Pareceu-me adequado ao que pretendo, mas começa logo por me
> pedir para confiar nas "magias" que o autor sugere à partida!...
> desiludiu-me um bocado.

Meu método é esse mesmo --- um livro pra cada ferramenta que uso. Por
exemplo, o livro do /ls/ você encontra ao dizer

man ls

a seu shell. O GNU EMACS tem seus livros em si próprio. Tem
ferramentas que nos leverão a vários livros. Por exemplo, uma linguagem
de programação.

Você já deve ter visto por aí programas de uma só linha escritos em AWK.
Você já leu ``The AWK Programming Language''? Leia-o e compreenda-os.

Cara programa de computador funciona como uma linguagem de programação.
O /ls/ possui uma série de construtores de linguagem, o que você
descobre no livro. Todo programa-ls tem a forma

ls [OPTIONS]... [FILE]...

Estritamente falando, o programa não inclui o /ls/ porque, na verdade,
esse construtor inicial é de uma outra linguagem --- chamada usualmente
de /shell/. Então um programa-ls tem na verdade a forma

[OPTIONS]... [FILE]...

Conhecendo um mínimo sobre o shell e lendo o livro /ls/, compreender os
resultados abaixos é tarefa trivial. Sem ler o livro, é um trabalho
realmente difícil de ser feito.

--8<---------------cut here---------------start------------->8---
%ls -i Makefile*
12666373952139719 Makefile
4785074604376244 Makefile.~1~
12384898975409143 Makefile.~2~
18014398509613044 Makefile.~3~
--8<---------------cut here---------------end--------------->8---

--8<---------------cut here---------------start------------->8---
%ls -i -r Makefile*
18014398509613044 Makefile.~3~
12384898975409143 Makefile.~2~
4785074604376244 Makefile.~1~
12666373952139719 Makefile
--8<---------------cut here---------------end--------------->8---

O princípio que emerge aqui então é o princípio de que pra usar uma
ferramenta de computador é preciso estudá-la. Cada uma. O que parece
uma tarefa absurda, é na verdade muito sensata. O processo produz uma
grande economia de tempo.

Um artigo na Internet em média não tem o cuidado que um livro tem. Uma
pessoa escreve um livro usualmente pensando em fazer uma obra que dure
muitos anos, talvez pra sempre. Ainda lemos a República de Platão com
grande interesse. ``The C Programming Language'' de Brian Kernighan e
Dennis Ritchie ainda é provavelmente a melhor apresentação sobre C. E
mesmo que não fosse, sua importância história nos faz lê-lo. A gente
não estuda só pra saber usar uma ferramenta; a gente estuda também pra
entender o pensamento médio. Assuntos técnicos fluem numa comunidade e
é preciso entender a comunidade. Não se sugere que você leia qualquer
lixo. Muitos fenômenos técnicos hoje são na verdade propaganda.
Estudar a história do tema usualmente nos permite detectar o fato e
então dispensar o conteúdo comtemporâneo que é só propaganda, perda de
tempo e ilusão. (Mas aqui a gente entra em outro assunto.)

Com experiência, você não gasta seu tempo com livros que não são
interessantes e nem se envolve com movimentos que não são interessante.

Patricia Ferreira

unread,
Jan 12, 2024, 9:38:05 AM1/12/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Que bom! E que bom que você conhece C também.
>
> Sim, aprendi na Universidade do Minho. Infelizmente zero Lisp no curso
> de Engenharia Informática. Apenas Haskell.

Ou felizmente. Talvez você odiasse Lisp. É o que acontece com
matemática e português, dado que (quase) todas as crianças vão à escola.

>>> Patrícia, quais livros de Lisp leste, e quais recomendas? Que tipo de
>>> Lisp fala esses livros?
>>
>> Os livros de Lisp que realmente li foram o HtDP e o SICP. Tem muita
>> coisa a se conversar aí. O Practical Common Lisp vai te apresentar um
>> jeito Common Lisp de escrever, mas é preciso saber se você já tem um
>> pouco do jeito Lisp de pensar --- antes do jeito Common Lisp. Você tem
>> sentido alguma dificuldade em algum lugar que você consiga descrever? A
>> gente começa a conversa por aí.
>
> A dificuldade que tenho é apenas em decorar as várias funções/macros da
> linguagem.

Qual delas? Common Lisp?

> Fora isso tenho andado bem, a passo lento, com tempo para assimilação.

Vamos começar bem do zero e investigar onde estamos. (Estou assumindo
Common Lisp.) Qual seria um bom nome pro procedimento abaixo? Quanto
tempo você levou pra chegar a sua resposta?

(defun f (ls)
(cond
((null ls) nil)
((consp ls)
(or (string= (car ls) "gluten")
(f (cdr ls))))))

>> Estou iniciando com Common Lisp --- descobri esses dias. Não sabia que
>> era tão divertido usar Common Lisp. São poucos dias ainda, mas a gente
>> sabe o que gosta quando vê. É /absolutamente/ a melhor experiência que
>> já tive. Uso o GNU EMACS há muitos anos. Agora estou usando SLIME e
>> SBCL. Estou me divertindo *muito mais* com SBCL e SLIME do que com
>> Racket e racket-mode. Muito mais. As mensagens de erro do SBCL são
>> maravilhosas comparadas às mensagens de erro de Racket.
>
> Que bom que também partilhas este prazer. Escrever Common Lisp é
> maravilhoso. Principalmente com o GNU Emacs.
>
> Eu não uso SLIME porque não dá para criar imagens lisp com o SLIME. Uso
> M-x run-lisp , e assim já consigo usar o save-lisp-and-die. Tenho uma
> atitute minimalista com o software, uso apenas aquilo que realmente
> preciso, tento não usar dois softwares que fazem a mesma coisa.

Mas assim você não tem uma integração entre seu buffer no GNU EMACS e o
*inferior-lisp*. Você não vai usar save-lisp-and-die o tempo todo.
Lembre-se de que você pode e deve manter o estado do seu programa num
programa.lisp. Você consegue reproduzir a imagem de Lisp sempre. Não
precisa salvá-la por completo assim.

> Patricia, eu li e recomendo ler, os livros do John McCarthy sobre Lisp.

Vamos enumerar esses livros. Qual o primeiro que você recomenda?

> Que personagem. Dá para ver nos livros dele que ele era uma pessoa
> brilhante. São simples e fácil de entender. Quem lê, fica a saber a
> raíz por onde começou. Que é a melhor maneira de adquirir conhecimento.
>
> Um dos seus websites é: http://www-formal.stanford.edu/jmc/

Maravilha. Vamos lembrar também que quando John McCarthy inventou Lisp,
ele não pensava na linguagem como uma linguagem de programação. Foi
Steve Russell, orientando de John McCarthy que viu que o procedimento
/eval/ poderia e deveria virar um programa de computador. Quando John
McCarthy ouviu a ideia direto do próprio Steve Russell, ele achou que o
Steve Russell estava viajando. A história é contada pelo próprio
McCarthy.

Daniel Cerqueira

unread,
Jan 12, 2024, 1:22:39 PM1/12/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Ou felizmente. Talvez você odiasse Lisp. É o que acontece com
> matemática e português, dado que (quase) todas as crianças vão à escola.

Aí tens razão. Embora eu goste muito da matemática que aprendi na escola.

>> A dificuldade que tenho é apenas em decorar as várias funções/macros da
>> linguagem.
>
> Qual delas? Common Lisp?

Sim, de Common Lisp. Acho que falta um livro, que eu conheça, mais
sucinto sobre Common Lisp. Embora esta seja uma linguagem grande.

O que mais se parece com um livro sucinto de Common Lisp, que eu
conheça, é o "The Little Lisper" (está em archive.org). É um ótimo livro
para aprender Lisp.

> Vamos começar bem do zero e investigar onde estamos. (Estou assumindo
> Common Lisp.) Qual seria um bom nome pro procedimento abaixo? Quanto
> tempo você levou pra chegar a sua resposta?
>
> (defun f (ls)
> (cond
> ((null ls) nil)
> ((consp ls)
> (or (string= (car ls) "gluten")
> (f (cdr ls))))))
>

Eu chamaria de search-for-gluten. Embora seja algo que se deva evitar
:-)

Retorna t caso uma lista tenha como primeiro átomo a string "gluten".

Não tenho bem a certeza o que é consp, mas deve ser para retornar t caso
seja uma lista. Eu faria essa função de maneira diferente. Tipo:

(defun search-for-gluten (list)
(cond
((null list) nil)
((string= (car list) "gluten") t)
(t (search-for-gluten (cdr list)))))

Também se pode chamar a esta função de gluten-p ou glutenp .

Acho que a minha função é mais legível que a tua :-P eheheh.

>> Eu não uso SLIME porque não dá para criar imagens lisp com o SLIME. Uso
>> M-x run-lisp , e assim já consigo usar o save-lisp-and-die. Tenho uma
>> atitute minimalista com o software, uso apenas aquilo que realmente
>> preciso, tento não usar dois softwares que fazem a mesma coisa.
>
> Mas assim você não tem uma integração entre seu buffer no GNU EMACS e o
> *inferior-lisp*. Você não vai usar save-lisp-and-die o tempo todo.
> Lembre-se de que você pode e deve manter o estado do seu programa num
> programa.lisp. Você consegue reproduzir a imagem de Lisp sempre. Não
> precisa salvá-la por completo assim.

Tenho integração com o *inferior-lisp*. Quero dizer, isto abre-me a
consola SBCL. Tenho acesso a C-c C-c e outras keybindings para
programação com Lisp.

Sim, não vou estar sempre a guardar imagens. Mas não gosto que SLIME
retire esta funcionalidade (que eu considero importante). Eu guardo os
meus programas lisp em ficheiros .lisp .

>> Patricia, eu li e recomendo ler, os livros do John McCarthy sobre Lisp.
>
> Vamos enumerar esses livros. Qual o primeiro que você recomenda?

1. http://www-formal.stanford.edu/jmc/recursive.html
2. o livro de LISP 1.5 Programmers Manual. Ainda me falta ler este
(estou agora a ler o PCL).

>> Um dos seus websites é: http://www-formal.stanford.edu/jmc/
>
> Maravilha. Vamos lembrar também que quando John McCarthy inventou Lisp,
> ele não pensava na linguagem como uma linguagem de programação. Foi
> Steve Russell, orientando de John McCarthy que viu que o procedimento
> /eval/ poderia e deveria virar um programa de computador. Quando John
> McCarthy ouviu a ideia direto do próprio Steve Russell, ele achou que o
> Steve Russell estava viajando. A história é contada pelo próprio
> McCarthy.

Sim. É muito interessante essa história.
Steve Russell fez o programa de computador de LISP em assembly, tanto
quanto sei.

PS:
Penso que o meu domínio vai expirar no fim deste mês. Se vires eu
responder com outro endereço depois deste mês, não estranhes. Tens chave
OpenPGP?

Ninguém

unread,
Jan 12, 2024, 1:51:21 PM1/12/24
to
Daniel Cerqueira (dan....@brilhante.top) escreveu no dia 2024-01-12
(Friday), cerca das 18:22 +0000:
> Penso que o meu domínio vai expirar no fim deste mês.

E?...
Vais deixar expirar? Mexe-te pá! Revalida. Não?!...

Patricia Ferreira

unread,
Jan 12, 2024, 3:01:22 PM1/12/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Ou felizmente. Talvez você odiasse Lisp. É o que acontece com
>> matemática e português, dado que (quase) todas as crianças vão à escola.
>
> Aí tens razão. Embora eu goste muito da matemática que aprendi na escola.

Então provavelmente você ia gostar de Lisp também.

>>> A dificuldade que tenho é apenas em decorar as várias funções/macros da
>>> linguagem.
>>
>> Qual delas? Common Lisp?
>
> Sim, de Common Lisp. Acho que falta um livro, que eu conheça, mais
> sucinto sobre Common Lisp. Embora esta seja uma linguagem grande.

Você vai achar o

ANSI Common Lisp, Paul Graham, 1996, ISBN 0-13-370875-6

sucinto. Obtenha uma versão eletrônica pra você fazer buscas por ele.

> O que mais se parece com um livro sucinto de Common Lisp, que eu
> conheça, é o "The Little Lisper" (está em archive.org). É um ótimo livro
> para aprender Lisp.

Sim, mas não é Common Lisp.

>> Vamos começar bem do zero e investigar onde estamos. (Estou assumindo
>> Common Lisp.) Qual seria um bom nome pro procedimento abaixo? Quanto
>> tempo você levou pra chegar a sua resposta?
>>
>> (defun f (ls)
>> (cond
>> ((null ls) nil)
>> ((consp ls)
>> (or (string= (car ls) "gluten")
>> (f (cdr ls))))))
>>
>
> Eu chamaria de search-for-gluten. Embora seja algo que se deva evitar
> :-)

O que que se deve evitar?

> Retorna t caso uma lista tenha como primeiro átomo a string "gluten".

O procedimento retorna true caso a string "gluten" esteja em qualquer
posição da lista /ls/. Isso não me parece uma ``falta de atenção''.
Isso me parece falta de intimidade com o assunto. Vai-lhe ser útil ler
o HtDP. Você vai compreender esses padrões e muito mais.

> Não tenho bem a certeza o que é consp, mas deve ser para retornar t caso
> seja uma lista.

Isso. Em maior generalidade, retorna true caso o argumento seja um
``cons''. Uma lista é uma sequência de /cons/es.

> Eu faria essa função de maneira diferente. Tipo:
>
> (defun search-for-gluten (list)
> (cond
> ((null list) nil)
> ((string= (car list) "gluten") t)
> (t (search-for-gluten (cdr list)))))
>
> Também se pode chamar a esta função de gluten-p ou glutenp .
>
> Acho que a minha função é mais legível que a tua :-P eheheh.

Knock yourself out. :-)

Vejamos um próximo exercício?

(*) Exercício 2

Escreva um procedimento f que consome duas listas de números inteiros em
ordem ascendente. O procedimento f retorna uma única lista ordenada de
números que contenha todos os números de ambas listas de entrada. Um
número ocorre na saída tantas vezes quando ocorre em ambas as listas de
entrada. Quando tempo você levou pra escrever o procedimento?

>>> Patricia, eu li e recomendo ler, os livros do John McCarthy sobre Lisp.
>>
>> Vamos enumerar esses livros. Qual o primeiro que você recomenda?
>
> 1. http://www-formal.stanford.edu/jmc/recursive.html

Interessante. Você chama isso de livro? Eu chamo de artigo.

> 2. o livro de LISP 1.5 Programmers Manual. Ainda me falta ler este
> (estou agora a ler o PCL).

Por que é recomendado?

> PS:
> Penso que o meu domínio vai expirar no fim deste mês. Se vires eu
> responder com outro endereço depois deste mês, não estranhes.

Olha, veja como vejo o thread:

--8<---------------cut here---------------start------------->8---
+[R][252] 12-Jan DAN> Re: Lisp, um mapa de trajeto [94L]
[R][253] 12-Jan NIN\-> Re: Lisp, um mapa de trajeto [7L]
--8<---------------cut here---------------end--------------->8---

Qualquer /Dan/ por aqui se confunde com você. É legal não saber com
quem se fala. Penso em escrever um servidor NNTP que sempre troca o
from da pessoa por um nome aleatório qualquer.

> Tens chave OpenPGP?

Tenho várias.

Daniel Cerqueira

unread,
Jan 12, 2024, 5:26:44 PM1/12/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> Patricia Ferreira <pfer...@example.com> writes:
>>
>>> Vamos começar bem do zero e investigar onde estamos. (Estou assumindo
>>> Common Lisp.) Qual seria um bom nome pro procedimento abaixo? Quanto
>>> tempo você levou pra chegar a sua resposta?
>>>
>>> (defun f (ls)
>>> (cond
>>> ((null ls) nil)
>>> ((consp ls)
>>> (or (string= (car ls) "gluten")
>>> (f (cdr ls))))))
>>>
>>
>> Eu chamaria de search-for-gluten. Embora seja algo que se deva evitar
>> :-)
>
> O que que se deve evitar?
>

Comer gluten :-P

>> Retorna t caso uma lista tenha como primeiro átomo a string "gluten".
>
> O procedimento retorna true caso a string "gluten" esteja em qualquer
> posição da lista /ls/. Isso não me parece uma ``falta de atenção''.
> Isso me parece falta de intimidade com o assunto. Vai-lhe ser útil ler
> o HtDP. Você vai compreender esses padrões e muito mais.
>

Sim, tens razão. Não estava a pensar direito. Eu sei que vai fazendo car
a todos os elementos da lista. Desculpa o erro. Não é falta de
conhecimento, neste caso. Foi distração, também vinda da falta de ter
feito um teste a esse código.

> Knock yourself out. :-)
>
> Vejamos um próximo exercício?
>
> (*) Exercício 2
>
> Escreva um procedimento f que consome duas listas de números inteiros em
> ordem ascendente. O procedimento f retorna uma única lista ordenada de
> números que contenha todos os números de ambas listas de entrada. Um
> número ocorre na saída tantas vezes quando ocorre em ambas as listas de
> entrada. Quando tempo você levou pra escrever o procedimento?
>

Fácil! Acabei de ler precisamente esse capítulo do PCL. Foi só o tempo
de procurar como é a sintaxe do sort. Diria que demorei 1 minuto.

(defun f (a b)
(sort (append a b) #'<))

>>>> Patricia, eu li e recomendo ler, os livros do John McCarthy sobre Lisp.
>>>
>>> Vamos enumerar esses livros. Qual o primeiro que você recomenda?
>>
>> 1. http://www-formal.stanford.edu/jmc/recursive.html
>
> Interessante. Você chama isso de livro? Eu chamo de artigo.
>

Sim, é um artigo. :-P

>> 2. o livro de LISP 1.5 Programmers Manual. Ainda me falta ler este
>> (estou agora a ler o PCL).
>
> Por que é recomendado?
>

Para entender melhor o Lisp 1.5. Isto faz com que se compreenda melhor
os Lisp atuais. Lisp 1.5 é importante por ser o Lisp antes da
divergência que ocorreu com o nascimento dos vários Lisps. Também por
ser um livro de McCarthy.

>> Tens chave OpenPGP?
>
> Tenho várias.

Podes-me enviar uma das tuas chaves por email? O meu email está no
cabeçalho. Assim quando eu mudar de email, ficas a continuar a saber que
sou eu (caso eu assine as mensagens NNTP, que estou a pensar em começar
a fazer).

Daniel Cerqueira

unread,
Jan 12, 2024, 5:29:27 PM1/12/24
to
Sim, não vou revalidar. Vou mesmo mudar de domínio. O .top é muito usado
por spammers e às vezes os meus emails não são entregues por os filtros
de spam não gostarem de endereços .top.

Patricia Ferreira

unread,
Jan 12, 2024, 6:28:04 PM1/12/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

[...]

> Sim, não vou revalidar. Vou mesmo mudar de domínio. O .top é muito usado
> por spammers e às vezes os meus emails não são entregues por os filtros
> de spam não gostarem de endereços .top.

Não acredito que os filtros tenham qualquer coisa contra o .top. Você
pode simplesmente ser desconhecido demais pra ter grande consideração
pelos filtros. Qual o percentual de usuários de e-mail que usam Gmail
ou Hotmail ou Yahoo? Não acho que vão fazer sua vida muito fácil.
Hospedar seu próprio e-mail hoje não é tarefa trivial.

https://cfenollosa.com/blog/after-self-hosting-my-email-for-twenty-three-years-i-have-thrown-in-the-towel-the-oligopoly-has-won.html

Patricia Ferreira

unread,
Jan 12, 2024, 6:50:15 PM1/12/24
to
Amizade é nunca ter que pedir desculpas. -- Love Story, 1970.

>> Vejamos um próximo exercício?
>>
>> (*) Exercício 2
>>
>> Escreva um procedimento f que consome duas listas de números inteiros em
>> ordem ascendente. O procedimento f retorna uma única lista ordenada de
>> números que contenha todos os números de ambas listas de entrada. Um
>> número ocorre na saída tantas vezes quando ocorre em ambas as listas de
>> entrada. Quando tempo você levou pra escrever o procedimento?
>
> Fácil! Acabei de ler precisamente esse capítulo do PCL. Foi só o tempo
> de procurar como é a sintaxe do sort. Diria que demorei 1 minuto.
>
> (defun f (a b)
> (sort (append a b) #'<))

Solução correta, o nos obriga a fazer um patch no exercício: o espírito
do exercício não é esse. O exercício não está buscando detectar se você
conhece a sintaxe Common Lisp. O exercício que se saber se você pensa
como um programador Lisp. O primeiro exercício queria ver se você
reconhecia a varredura de /uma/ lista. O segundo agora quer saber se
você consegue varrer duas listas ao mesmo tempo. Vai-lhe ser útil ler o
HtDP.

(*) Exercício 2 patch-1

Use apenas cond, null, car, cdr e <. Escreva um procedimento f que
consome duas listas de números inteiros em ordem ascendente. O
procedimento f retorna uma única lista ordenada de números que contenha
todos os números de ambas listas de entrada. Um número ocorre na saída
tantas vezes quando ocorre em ambas as listas de entrada. Quando tempo
você levou pra escrever o procedimento?

>>>>> Patricia, eu li e recomendo ler, os livros do John McCarthy sobre Lisp.
>>>>
>>>> Vamos enumerar esses livros. Qual o primeiro que você recomenda?
>>>
>>> 1. http://www-formal.stanford.edu/jmc/recursive.html
>>
>> Interessante. Você chama isso de livro? Eu chamo de artigo.
>>
>
> Sim, é um artigo. :-P
>
>>> 2. o livro de LISP 1.5 Programmers Manual. Ainda me falta ler este
>>> (estou agora a ler o PCL).
>>
>> Por que é recomendado?
>
> Para entender melhor o Lisp 1.5. Isto faz com que se compreenda melhor
> os Lisp atuais. Lisp 1.5 é importante por ser o Lisp antes da
> divergência que ocorreu com o nascimento dos vários Lisps. Também por
> ser um livro de McCarthy.

Legal.

>>> Tens chave OpenPGP?
>>
>> Tenho várias.
>
> Podes-me enviar uma das tuas chaves por email? O meu email está no
> cabeçalho. Assim quando eu mudar de email, ficas a continuar a saber que
> sou eu (caso eu assine as mensagens NNTP, que estou a pensar em começar
> a fazer).

Olha, não uso e-mail criptografado. Posso te mandar uma chave minha,
mas não vai me ser nada conveniente descriptografar qualquer coisa que
você me envie por e-mail --- nunca instalei qualquer mecanismo de rápida
criptografia ou descriptografia.

Nuno Silva

unread,
Jan 13, 2024, 5:33:24 AM1/13/24
to
(Ainda não li esse artigo mas penso que já o tenho numa lista para, com
tempo, ler)

A Microsoft (Outlook) é conhecida por ter algumas regras que
efectivamente estabelecem uma fasquia quase impossível, ou aliás,
contraditória: para considerarem que um servidor tem reputação, é
preciso que esse servidor envie muito correio. Ou seja, os spammers se
calhar têm mais sorte do que as pessoas que querem apenas manter o seu
próprio servidor para uso pessoal...


A Microsoft também é conhecida, embora isto não afecte o produto
gratuito anteriormente chamado de "Hotmail", por ter uma funcionalidade
"de segurança" em que algumas mensagens podem ser retidas na
"quarentena", que não é uma pasta de correio, e portanto significa que,
a não ser que o destinatário conheça a quarentena e a consulte
ocasionalmente, possivelmente não terá sequer conhecimento de que lhe
foram enviadas as mensagens retidas. Imagino que isto em particular seja
uma causa significativa de problemas na entrega de correio a endereços
geridos pela Microsoft.


Talvez esteja na altura de recomendar fortemente a outras pessoas que
não utilizem Microsoft para e-mail. Ou de ter um endereço alternativo
para mensagens vindas de fora.


Yahoo/Aol/Verizon/... também merece recomendação para se evitar, mas por
outra razão: querem mesmo utilizar um serviço de correio cujos
servidores de envio volta e meia escangalham utf8?

https://bugzilla.mozilla.org/show_bug.cgi?id=1435903

--
Nuno Silva

Nuno Silva

unread,
Jan 13, 2024, 6:03:03 AM1/13/24
to
On 2024-01-12, Patricia Ferreira wrote:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> Patricia Ferreira <pfer...@example.com> writes:
>>
>>> Vejamos um próximo exercício?
>>>
>>> (*) Exercício 2
>>>
>>> Escreva um procedimento f que consome duas listas de números inteiros em
>>> ordem ascendente. O procedimento f retorna uma única lista ordenada de
>>> números que contenha todos os números de ambas listas de entrada. Um
>>> número ocorre na saída tantas vezes quando ocorre em ambas as listas de
>>> entrada. Quando tempo você levou pra escrever o procedimento?
>>
>> Fácil! Acabei de ler precisamente esse capítulo do PCL. Foi só o tempo
>> de procurar como é a sintaxe do sort. Diria que demorei 1 minuto.
>>
>> (defun f (a b)
>> (sort (append a b) #'<))
>
> Solução correta, o nos obriga a fazer um patch no exercício: o espírito
> do exercício não é esse. O exercício não está buscando detectar se você
> conhece a sintaxe Common Lisp. O exercício que se saber se você pensa
> como um programador Lisp. O primeiro exercício queria ver se você
> reconhecia a varredura de /uma/ lista. O segundo agora quer saber se
> você consegue varrer duas listas ao mesmo tempo. Vai-lhe ser útil ler o
> HtDP.

Há, nesta versão, também uma questão de menor eficiência, certo?
Percorre a, e depois percorre a lista mais longa "a+b", quando uma outra
solução (possivelmente a que tens em mente) só percorre cada lista uma
vez, portanto só "a+b"?

> (*) Exercício 2 patch-1
>
> Use apenas cond, null, car, cdr e <. Escreva um procedimento f que

Não falta aí cons? (Estou a pensar que talvez se conseguisse fazer a
lista do resultado com a notação para cons cell "(a.b)", `backtick` e
vírgula), mas provavelmente aqui o objectivo é usar cons?)

> consome duas listas de números inteiros em ordem ascendente. O
> procedimento f retorna uma única lista ordenada de números que contenha
> todos os números de ambas listas de entrada. Um número ocorre na saída
> tantas vezes quando ocorre em ambas as listas de entrada. Quando tempo
> você levou pra escrever o procedimento?

--
Nuno Silva

Patricia Ferreira

unread,
Jan 13, 2024, 7:46:43 AM1/13/24
to
O objetivo do exercício não é performance, não. (Também não vejo
qualquer diferença de performance, não. Talvez /sort/ até a versão mais
rápida porque ela trabalha in-place.)

>> (*) Exercício 2 patch-1
>>
>> Use apenas cond, null, car, cdr e <. Escreva um procedimento f que
>
> Não falta aí cons?

Falta.

> (Estou a pensar que talvez se conseguisse fazer a lista do resultado
> com a notação para cons cell "(a.b)", `backtick` e vírgula), mas
> provavelmente aqui o objectivo é usar cons?)

Boa solução, exceto que o exercício não disse que poderia usar quote ou
quasiquote. :-) Se sairmos do que é permitido, então usemos cons mesmo.

>> consome duas listas de números inteiros em ordem ascendente. O
>> procedimento f retorna uma única lista ordenada de números que contenha
>> todos os números de ambas listas de entrada. Um número ocorre na saída
>> tantas vezes quando ocorre em ambas as listas de entrada. Quando tempo
>> você levou pra escrever o procedimento?

(*) Exercício 2 patch-2

Use apenas cond, null, car, cdr, cons e <. Escreva um procedimento f

Daniel Cerqueira

unread,
Jan 13, 2024, 8:04:40 AM1/13/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
> [...]
>
>> Sim, não vou revalidar. Vou mesmo mudar de domínio. O .top é muito usado
>> por spammers e às vezes os meus emails não são entregues por os filtros
>> de spam não gostarem de endereços .top.
>
> Não acredito que os filtros tenham qualquer coisa contra o .top. Você
> pode simplesmente ser desconhecido demais pra ter grande consideração
> pelos filtros. Qual o percentual de usuários de e-mail que usam Gmail
> ou Hotmail ou Yahoo? Não acho que vão fazer sua vida muito fácil.
> Hospedar seu próprio e-mail hoje não é tarefa trivial.

Tenho email com domínio pessoal à mais de 4 anos, e estão a tentar
ensinar-me sobre isso. Ridículo.

Não sei se já repararam mas o meu endereço de email já tem o meu domínio
pessoal. Agora, neste momento. Eu sei o que falo quando algo é sobre
email e domínios.

Infelizmente, algo que não sabia anteriormente, os filtros de SPAM
também prejudicam a pontuação de SPAM, por TLD (top level domain).
Alguns TLDs tem a pontuação de SPAM penalizada, como o .top .

As contas de email da Riseup, por exemplo, rejeitam os meus emails
vindos de .top . Até agora, foi a única que me rejeitou os meus emails,
mas acredito que há muitos servidores que aumentam (e entregam) a minha
pontuação de SPAM.

Só aceito conselhos, vindos de um endereço com domínio pessoal.

Daniel Cerqueira

unread,
Jan 13, 2024, 8:32:20 AM1/13/24
to
Patricia Ferreira <pfer...@example.com> writes:

> (*) Exercício 2 patch-1
>
> Use apenas cond, null, car, cdr e <. Escreva um procedimento f que
> consome duas listas de números inteiros em ordem ascendente. O
> procedimento f retorna uma única lista ordenada de números que contenha
> todos os números de ambas listas de entrada. Um número ocorre na saída
> tantas vezes quando ocorre em ambas as listas de entrada. Quando tempo
> você levou pra escrever o procedimento?

Demorei à volta de 3 minutos.

(defun ordenar (a b)
(cond
((null a) b)
((null b) a)
((< (car a) (car b)) (cons (car a) (ordenar (cdr a) b)))
(t (cons (car b) (ordenar a (cdr b))))))

> Olha, não uso e-mail criptografado. Posso te mandar uma chave minha,
> mas não vai me ser nada conveniente descriptografar qualquer coisa que
> você me envie por e-mail --- nunca instalei qualquer mecanismo de rápida
> criptografia ou descriptografia.

Bem, ter várias chaves OpenPGP dá a sensação de saber usá-las para
cifrar emails.

Bem, quem quiser ficar com a minha chave pública OpenPGP, envie-me um
email.

Eu sou o tradutor para Português do GnuPG (as minhas traduções só vão
entrar na próxima versão - 2.4.4). Em breve a minha chave será alterada
para os meus novos endereços.

Patricia Ferreira

unread,
Jan 13, 2024, 2:59:47 PM1/13/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> (*) Exercício 2 patch-1
>>
>> Use apenas cond, null, car, cdr e <. Escreva um procedimento f que
>> consome duas listas de números inteiros em ordem ascendente. O
>> procedimento f retorna uma única lista ordenada de números que contenha
>> todos os números de ambas listas de entrada. Um número ocorre na saída
>> tantas vezes quando ocorre em ambas as listas de entrada. Quando tempo
>> você levou pra escrever o procedimento?
>
> Demorei à volta de 3 minutos.
>
> (defun ordenar (a b)
> (cond
> ((null a) b)
> ((null b) a)
> ((< (car a) (car b)) (cons (car a) (ordenar (cdr a) b)))
> (t (cons (car b) (ordenar a (cdr b))))))

Muito bom! Agora acreditamos em falta de atenção no anterior. Um nome
melhor pra esse procedimento seria /merge/. Com ele você implementa o
seu /ordenar/ --- que se chama /merge sort/, um respeitoso algoritmo.

(*) Exercício 3

Considere a lista abaixo como uma representação pra um grafo
direcionado.

(defparameter sample-graph
'((A (B E))
(B (E F))
(C (D))
(D ())
(E (C F))
(F (D G))
(G ())))

Os vertices são o que você espera --- A, B, C, ..., G. A lista
associada a um vértice /v/ representa os outros vértices a que /v/ tem
acesso. Por exemplo, A tem aresta pra B, mas B não tem aresta pra A.
Escreva um procedimento chamado /find-path/ tal que

(find-path 'C 'D sample-graph) produza '(C D)
(find-path 'E 'D sample-graph) produza '((E F D) (E C D))
(find-path 'C 'G sample-graph) produza nil

Quando terminar de fazer, veja o tempo que levou.

>> Olha, não uso e-mail criptografado. Posso te mandar uma chave minha,
>> mas não vai me ser nada conveniente descriptografar qualquer coisa que
>> você me envie por e-mail --- nunca instalei qualquer mecanismo de rápida
>> criptografia ou descriptografia.
>
> Bem, ter várias chaves OpenPGP dá a sensação de saber usá-las para
> cifrar emails. [...] Bem, quem quiser ficar com a minha chave pública
> OpenPGP, envie-me um email.

Já entendi. Você quer brincar de criptografia. Podemos brincar. Por
que você não explicou antes? Eis minha chave:

-----BEGIN RSA PRIVATE KEY-----
e4B...^C^C

Lol! Essa foi por pouco. (Estão rindo de quê? Tenho enorme
experiência com criptografia. Ridículo.) Lol.

-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA0eTpkgBTghWSEr8UsoqX
yTac3Cx3QBal/UG5xbP/6oaWo9f3uzS5smvzN6uBopjeDxf7YqFLmXeIqk1kfBd0
osFhMhFnGqsLnfQ6q+Kv0qMMOa9cWC2V53K5yoQ3EoxR1kJJ8wDmsc/Dio7Uqz/f
Wb1vXIrjzqCuwbHEeu0A4cqCh9GWdcgUubbzgN5h/SNMkrWl9nikyyxqK7zOjIm3
6ET5Ag4c3Zwp9w1+wMpxz39vdAtp82knQuVgyBwKTJX4U15NTWhdk09tXI8i/e8d
JtZXk8SDY5rYgELryZvecPMH5ik03z+8i09vuga/IelpZ6w2GmxM20yDFNzBF84F
iQIBJQ==
-----END PUBLIC KEY-----

Patricia Ferreira

unread,
Jan 13, 2024, 3:02:15 PM1/13/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Daniel Cerqueira <dan....@brilhante.top> writes:
>>
>> [...]
>>
>>> Sim, não vou revalidar. Vou mesmo mudar de domínio. O .top é muito usado
>>> por spammers e às vezes os meus emails não são entregues por os filtros
>>> de spam não gostarem de endereços .top.
>>
>> Não acredito que os filtros tenham qualquer coisa contra o .top. Você
>> pode simplesmente ser desconhecido demais pra ter grande consideração
>> pelos filtros. Qual o percentual de usuários de e-mail que usam Gmail
>> ou Hotmail ou Yahoo? Não acho que vão fazer sua vida muito fácil.
>> Hospedar seu próprio e-mail hoje não é tarefa trivial.
>
> Tenho email com domínio pessoal à mais de 4 anos, e estão a tentar
> ensinar-me sobre isso. Ridículo.

Lol! Como a gente ia saber que você é o gostosão dos e-mails? Perdôe
nossa insolência.

> Não sei se já repararam mas o meu endereço de email já tem o meu domínio
> pessoal. Agora, neste momento. Eu sei o que falo quando algo é sobre
> email e domínios.

Tá bom, tá bom, mas não se irrite. Realmente --- seu endereço de e-mail
é top e brilhante.

Ninguém

unread,
Jan 14, 2024, 5:12:01 AM1/14/24
to
On 13/01/24 19:59, Patricia Ferreira wrote:
> Já entendi. Você quer brincar de criptografia. Podemos brincar.
Eu gostava de "brincar de criptografia" com vocês? Posso? Quem é o dono
da bola?

Para começar, ajudem-me a perceber como gerir as chaves pgp (gpg).
Dentro de ~/.gnupg/ tenho:
pubring.kbx (GPG keybox database)
trustdb.gpg (GPG key trust database)

O que são cada uma delas (o que contêm)?

Ninguém

unread,
Jan 14, 2024, 5:33:48 AM1/14/24
to
On 13/01/24 13:04, Daniel Cerqueira wrote:
> Tenho email com domínio pessoal à mais de 4 anos, e estão a tentar
> ensinar-me sobre isso.

Então ensina tu.

Eu gostava de alojar o meu email, mas tenho medo de tornar o sistema
falível.
Já percebi que há um sistema de reputação, enviesado pelos grandes, que
torna quase impossível não cair na lista de classificações de reputação.
A classificação considera (do que vi):
- bloco de endereços IP
- reputação do servidor
- reputação do domínio
- reputação do TLD (essa não sabia, mas faz sentido...)
- configurações específicas do servidor (TLS)
- configuração do DNS (dkim, dmark, spf, PTR)
- claro: comportamento - se andar a mandar spam...
- comportamento dos destinatários - se me registarem como spam...

Que mais?

Daniel Cerqueira

unread,
Jan 14, 2024, 7:02:45 AM1/14/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Muito bom! Agora acreditamos em falta de atenção no anterior. Um nome
> melhor pra esse procedimento seria /merge/. Com ele você implementa o
> seu /ordenar/ --- que se chama /merge sort/, um respeitoso algoritmo.
>
> (*) Exercício 3
>
> Considere a lista abaixo como uma representação pra um grafo
> direcionado.
>
> (defparameter sample-graph
> '((A (B E))
> (B (E F))
> (C (D))
> (D ())
> (E (C F))
> (F (D G))
> (G ())))
>
> Os vertices são o que você espera --- A, B, C, ..., G. A lista
> associada a um vértice /v/ representa os outros vértices a que /v/ tem
> acesso. Por exemplo, A tem aresta pra B, mas B não tem aresta pra A.
> Escreva um procedimento chamado /find-path/ tal que
>
> (find-path 'C 'D sample-graph) produza '(C D)
> (find-path 'E 'D sample-graph) produza '((E F D) (E C D))
> (find-path 'C 'G sample-graph) produza nil
>
> Quando terminar de fazer, veja o tempo que levou.

É para resolver usando Common Lisp, ou o Lisp simples (como do último
exercício)? Tens de me dizer isso.

Também é para criar apenas uma função? Recursiva? Ou posso usar
quaisquer outras funções?

> Já entendi. Você quer brincar de criptografia. Podemos brincar. Por
> que você não explicou antes? Eis minha chave:
>
> -----BEGIN RSA PRIVATE KEY-----
> e4B...^C^C
>
> Lol! Essa foi por pouco. (Estão rindo de quê? Tenho enorme
> experiência com criptografia. Ridículo.) Lol.

Ahahahah! Essa foi boa!

> -----BEGIN PUBLIC KEY-----
> MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA0eTpkgBTghWSEr8UsoqX
> yTac3Cx3QBal/UG5xbP/6oaWo9f3uzS5smvzN6uBopjeDxf7YqFLmXeIqk1kfBd0
> osFhMhFnGqsLnfQ6q+Kv0qMMOa9cWC2V53K5yoQ3EoxR1kJJ8wDmsc/Dio7Uqz/f
> Wb1vXIrjzqCuwbHEeu0A4cqCh9GWdcgUubbzgN5h/SNMkrWl9nikyyxqK7zOjIm3
> 6ET5Ag4c3Zwp9w1+wMpxz39vdAtp82knQuVgyBwKTJX4U15NTWhdk09tXI8i/e8d
> JtZXk8SDY5rYgELryZvecPMH5ik03z+8i09vuga/IelpZ6w2GmxM20yDFNzBF84F
> iQIBJQ==
> -----END PUBLIC KEY-----

Esta chave pública é inválida. O meu GnuPG não a importa.

Daniel Cerqueira

unread,
Jan 14, 2024, 7:07:44 AM1/14/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> Patricia Ferreira <pfer...@example.com> writes:
>>
>>> Daniel Cerqueira <dan....@brilhante.top> writes:
>>>
>>> [...]
>>>
>>>> Sim, não vou revalidar. Vou mesmo mudar de domínio. O .top é muito usado
>>>> por spammers e às vezes os meus emails não são entregues por os filtros
>>>> de spam não gostarem de endereços .top.
>>>
>>> Não acredito que os filtros tenham qualquer coisa contra o .top. Você
>>> pode simplesmente ser desconhecido demais pra ter grande consideração
>>> pelos filtros. Qual o percentual de usuários de e-mail que usam Gmail
>>> ou Hotmail ou Yahoo? Não acho que vão fazer sua vida muito fácil.
>>> Hospedar seu próprio e-mail hoje não é tarefa trivial.
>>
>> Tenho email com domínio pessoal à mais de 4 anos, e estão a tentar
>> ensinar-me sobre isso. Ridículo.
>
> Lol! Como a gente ia saber que você é o gostosão dos e-mails? Perdôe
> nossa insolência.

Dão conselhos a quem já percebe, sem serem pedidos.... "fico chateado, é
claro que fico chateado" (Gato Fedorento).

Gostosão dos e-mails.... :-) essa é engraçada.

>> Não sei se já repararam mas o meu endereço de email já tem o meu domínio
>> pessoal. Agora, neste momento. Eu sei o que falo quando algo é sobre
>> email e domínios.
>
> Tá bom, tá bom, mas não se irrite. Realmente --- seu endereço de e-mail
> é top e brilhante.

Ok. Ainda é de manhã (para mim), estou mais bem disposto. O brilhante e
top é uma anologia ao Sol.... é brilhante, e está no topo :-P

Patricia Ferreira

unread,
Jan 14, 2024, 8:39:07 AM1/14/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Daniel Cerqueira <dan....@brilhante.top> writes:
>>
>>> Patricia Ferreira <pfer...@example.com> writes:
>>>
>>>> Daniel Cerqueira <dan....@brilhante.top> writes:
>>>>
>>>> [...]
>>>>
>>>>> Sim, não vou revalidar. Vou mesmo mudar de domínio. O .top é muito usado
>>>>> por spammers e às vezes os meus emails não são entregues por os filtros
>>>>> de spam não gostarem de endereços .top.
>>>>
>>>> Não acredito que os filtros tenham qualquer coisa contra o .top. Você
>>>> pode simplesmente ser desconhecido demais pra ter grande consideração
>>>> pelos filtros. Qual o percentual de usuários de e-mail que usam Gmail
>>>> ou Hotmail ou Yahoo? Não acho que vão fazer sua vida muito fácil.
>>>> Hospedar seu próprio e-mail hoje não é tarefa trivial.
>>>
>>> Tenho email com domínio pessoal à mais de 4 anos, e estão a tentar
>>> ensinar-me sobre isso. Ridículo.
>>
>> Lol! Como a gente ia saber que você é o gostosão dos e-mails? Perdôe
>> nossa insolência.
>
> Dão conselhos a quem já percebe, sem serem pedidos.... "fico chateado, é
> claro que fico chateado" (Gato Fedorento).
>
> Gostosão dos e-mails.... :-) essa é engraçada.

Lol! Tiro meu chapéu pela sua tranquilidade.

A propósito, não compreendi o ``dão conselhos a quem já percebe, sem
serem pedidos...''. Parece uma diferença do uso de português --- você
pode substituir o ``percebe'' por outra coisa?

Falando em português, seu acento grave em ``à mais de 4 anos'' encontra
preposição e artigo onde não tem. O que tem ali é o verbo haver no
sentido de tempo de decorrido.

>>> Não sei se já repararam mas o meu endereço de email já tem o meu domínio
>>> pessoal. Agora, neste momento. Eu sei o que falo quando algo é sobre
>>> email e domínios.
>>
>> Tá bom, tá bom, mas não se irrite. Realmente --- seu endereço de e-mail
>> é top e brilhante.
>
> Ok. Ainda é de manhã (para mim), estou mais bem disposto.

:-)

> O brilhante e top é uma anologia ao Sol.... é brilhante, e está no
> topo :-P

Legal! Não tinha notado a possível alusão ao Sol.

Patricia Ferreira

unread,
Jan 14, 2024, 8:51:51 AM1/14/24
to
Como primeira versão, use apenas recursão, cons, cond, car, cdr e essas
coisas. Vamos dar uma olhada no algoritmo primeiro de uma forma pura.

>> Já entendi. Você quer brincar de criptografia. Podemos brincar. Por
>> que você não explicou antes? Eis minha chave:
>>
>> -----BEGIN RSA PRIVATE KEY-----
>> e4B...^C^C
>>
>> Lol! Essa foi por pouco. (Estão rindo de quê? Tenho enorme
>> experiência com criptografia. Ridículo.) Lol.
>
> Ahahahah! Essa foi boa!
>
>> -----BEGIN PUBLIC KEY-----
>> MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA0eTpkgBTghWSEr8UsoqX
>> yTac3Cx3QBal/UG5xbP/6oaWo9f3uzS5smvzN6uBopjeDxf7YqFLmXeIqk1kfBd0
>> osFhMhFnGqsLnfQ6q+Kv0qMMOa9cWC2V53K5yoQ3EoxR1kJJ8wDmsc/Dio7Uqz/f
>> Wb1vXIrjzqCuwbHEeu0A4cqCh9GWdcgUubbzgN5h/SNMkrWl9nikyyxqK7zOjIm3
>> 6ET5Ag4c3Zwp9w1+wMpxz39vdAtp82knQuVgyBwKTJX4U15NTWhdk09tXI8i/e8d
>> JtZXk8SDY5rYgELryZvecPMH5ik03z+8i09vuga/IelpZ6w2GmxM20yDFNzBF84F
>> iQIBJQ==
>> -----END PUBLIC KEY-----
>
> Esta chave pública é inválida. O meu GnuPG não a importa.

Que erro ele dá? Será que ele está querendo o tipo da chave? É uma
RSA. Eis o módulo e o expoente público:

--8<---------------cut here---------------start------------->8---
%openssl.exe rsa -in pub.txt -pubin -text
writing RSA key
RSA Public-Key: (2048 bit)
Modulus:
00:d1:e4:e9:92:00:53:82:15:92:12:bf:14:b2:8a:
97:c9:36:9c:dc:2c:77:40:16:a5:fd:41:b9:c5:b3:
ff:ea:86:96:a3:d7:f7:bb:34:b9:b2:6b:f3:37:ab:
81:a2:98:de:0f:17:fb:62:a1:4b:99:77:88:aa:4d:
64:7c:17:74:a2:c1:61:32:11:67:1a:ab:0b:9d:f4:
3a:ab:e2:af:d2:a3:0c:39:af:5c:58:2d:95:e7:72:
b9:ca:84:37:12:8c:51:d6:42:49:f3:00:e6:b1:cf:
c3:8a:8e:d4:ab:3f:df:59:bd:6f:5c:8a:e3:ce:a0:
ae:c1:b1:c4:7a:ed:00:e1:ca:82:87:d1:96:75:c8:
14:b9:b6:f3:80:de:61:fd:23:4c:92:b5:a5:f6:78:
a4:cb:2c:6a:2b:bc:ce:8c:89:b7:e8:44:f9:02:0e:
1c:dd:9c:29:f7:0d:7e:c0:ca:71:cf:7f:6f:74:0b:
69:f3:69:27:42:e5:60:c8:1c:0a:4c:95:f8:53:5e:
4d:4d:68:5d:93:4f:6d:5c:8f:22:fd:ef:1d:26:d6:
57:93:c4:83:63:9a:d8:80:42:eb:c9:9b:de:70:f3:
07:e6:29:34:df:3f:bc:8b:4f:6f:ba:06:bf:21:e9:
69:67:ac:36:1a:6c:4c:db:4c:83:14:dc:c1:17:ce:
05:89
Exponent: 37 (0x25)
-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA0eTpkgBTghWSEr8UsoqX
yTac3Cx3QBal/UG5xbP/6oaWo9f3uzS5smvzN6uBopjeDxf7YqFLmXeIqk1kfBd0
osFhMhFnGqsLnfQ6q+Kv0qMMOa9cWC2V53K5yoQ3EoxR1kJJ8wDmsc/Dio7Uqz/f
Wb1vXIrjzqCuwbHEeu0A4cqCh9GWdcgUubbzgN5h/SNMkrWl9nikyyxqK7zOjIm3
6ET5Ag4c3Zwp9w1+wMpxz39vdAtp82knQuVgyBwKTJX4U15NTWhdk09tXI8i/e8d
JtZXk8SDY5rYgELryZvecPMH5ik03z+8i09vuga/IelpZ6w2GmxM20yDFNzBF84F
iQIBJQ==
-----END PUBLIC KEY-----
--8<---------------cut here---------------end--------------->8---

Patricia Ferreira

unread,
Jan 14, 2024, 9:01:18 AM1/14/24
to
Ninguém <use...@rasparta.org> writes:

> On 13/01/24 19:59, Patricia Ferreira wrote:
>> Já entendi. Você quer brincar de criptografia. Podemos brincar.
> Eu gostava de "brincar de criptografia" com vocês? Posso? Quem é o
> dono da bola?

O dono da bola é o Eternal September --- da minha perspectiva.

> Para começar, ajudem-me a perceber como gerir as chaves pgp (gpg).
> Dentro de ~/.gnupg/ tenho:
> pubring.kbx (GPG keybox database)
> trustdb.gpg (GPG key trust database)
>
> O que são cada uma delas (o que contêm)?

O manual explica. O pubring.kbx, como o nome sugere, é o seu chaveiro.
Você pega a chave de alguém e guarda em algum lugar --- esse lugar é o
seu chaveiro. O trustdb.gpg é uma base de dados que armazena a rede de
confiança. Pra compreender o que é essa rede de confiança --- chamada
de /web of trust/, recomendo a leitura do manual, que vai explicar muito
melhor que qualquer parágrafo meu por aqui. Eis o trecho introdutório
do capítulo 2, ``concepts'', do ``The GNU Privacy Handbook''.

--8<---------------cut here---------------start------------->8---
(*) Validating other keys on your public keyring

In Chapter 1 a procedure was given to validate your correspondents'
public keys: a correspondent's key is validated by personally checking
his key's fingerprint and then signing his public key with your private
key. By personally checking the fingerprint you can be sure that the key
really does belong to him, and since you have signed they key, you can
be sure to detect any tampering with it in the future. Unfortunately,
this procedure is awkward when either you must validate a large number
of keys or communicate with people whom you do not know personally.

GnuPG addresses this problem with a mechanism popularly known as the web
of trust. In the web of trust model, responsibility for validating
public keys is delegated to people you trust. For example, suppose

Alice has signed Blake's key, and

Blake has signed Chloe's key and Dharma's key.

If Alice trusts Blake to properly validate keys that he signs, then
Alice can infer that Chloe's and Dharma's keys are valid without having
to personally check them. She simply uses her validated copy of Blake's
public key to check that Blake's signatures on Chloe's and Dharma's are
good. In general, assuming that Alice fully trusts everybody to properly
validate keys they sign, then any key signed by a valid key is also
considered valid. The root is Alice's key, which is axiomatically
assumed to be valid.
--8<---------------cut here---------------end--------------->8---

Ninguém

unread,
Jan 14, 2024, 9:18:55 AM1/14/24
to
On 14/01/24 14:01, Patricia Ferreira wrote:
> O pubring.kbx, como o nome sugere, é o seu chaveiro.
> Você pega a chave de alguém e guarda em algum lugar --- esse lugar é o
> seu chaveiro.

Isso. Mas a minha chave não tem só a parte pública. Tem também a porção
privada dela.
Onde fica guardada a minha chave privada, partindo do princípio que a
parte pública, ainda que minha, fique nesse ficheiro?

> O trustdb.gpg é uma base de dados que armazena a rede de
> confiança.

Entendi.

Patricia Ferreira

unread,
Jan 14, 2024, 9:33:45 AM1/14/24
to
Ninguém <use...@rasparta.org> writes:

> On 14/01/24 14:01, Patricia Ferreira wrote:
>> O pubring.kbx, como o nome sugere, é o seu chaveiro.
>> Você pega a chave de alguém e guarda em algum lugar --- esse lugar é o
>> seu chaveiro.
>
> Isso. Mas a minha chave não tem só a parte pública. Tem também a
> porção privada dela.
> Onde fica guardada a minha chave privada, partindo do princípio que a
> parte pública, ainda que minha, fique nesse ficheiro?

Parece que o GnuPG hoje armazena chaves privadas no diretório

~/.gnupg/private-keys-v1.d/

O manual gpg(1) diz:

--8<---------------cut here---------------start------------->8---
--secret-keyring file
This is an obsolete option and ignored. All secret keys are
stored in the `private-keys-v1.d' directory below the GnuPG home
directory.
--8<---------------cut here---------------end--------------->8---

Diga o capítulo 1 em

https://www.gnupg.org/gph/en/manual.html#INTRO

Depois de gerar sua chave, observe o diretório.

Nuno Silva

unread,
Jan 14, 2024, 10:43:23 AM1/14/24
to
On 2024-01-14, Patricia Ferreira wrote:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> Patricia Ferreira <pfer...@example.com> writes:
>>
>>> Já entendi. Você quer brincar de criptografia. Podemos brincar. Por
>>> que você não explicou antes? Eis minha chave:
>>>
>>> -----BEGIN RSA PRIVATE KEY-----
>>> e4B...^C^C
>>>
>>> Lol! Essa foi por pouco. (Estão rindo de quê? Tenho enorme
>>> experiência com criptografia. Ridículo.) Lol.
>>
>> Ahahahah! Essa foi boa!
>>
>>> -----BEGIN PUBLIC KEY-----
>>> MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA0eTpkgBTghWSEr8UsoqX
>>> yTac3Cx3QBal/UG5xbP/6oaWo9f3uzS5smvzN6uBopjeDxf7YqFLmXeIqk1kfBd0
>>> osFhMhFnGqsLnfQ6q+Kv0qMMOa9cWC2V53K5yoQ3EoxR1kJJ8wDmsc/Dio7Uqz/f
>>> Wb1vXIrjzqCuwbHEeu0A4cqCh9GWdcgUubbzgN5h/SNMkrWl9nikyyxqK7zOjIm3
>>> 6ET5Ag4c3Zwp9w1+wMpxz39vdAtp82knQuVgyBwKTJX4U15NTWhdk09tXI8i/e8d
>>> JtZXk8SDY5rYgELryZvecPMH5ik03z+8i09vuga/IelpZ6w2GmxM20yDFNzBF84F
>>> iQIBJQ==
>>> -----END PUBLIC KEY-----
>>
>> Esta chave pública é inválida. O meu GnuPG não a importa.
>
> Que erro ele dá? Será que ele está querendo o tipo da chave? É uma
> RSA. Eis o módulo e o expoente público:
>
>
> %openssl.exe rsa -in pub.txt -pubin -text

openssl? Estás a usar esta chave para OpenPGP ou para S/MIME?

--
Nuno Silva

Nuno Silva

unread,
Jan 14, 2024, 10:50:33 AM1/14/24
to
On 2024-01-14, Patricia Ferreira wrote:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> Patricia Ferreira <pfer...@example.com> writes:
>>
>>> Daniel Cerqueira <dan....@brilhante.top> writes:
[...]
>>>> Tenho email com domínio pessoal à mais de 4 anos, e estão a tentar
>>>> ensinar-me sobre isso. Ridículo.
>>>
>>> Lol! Como a gente ia saber que você é o gostosão dos e-mails? Perdôe
>>> nossa insolência.
>>
>> Dão conselhos a quem já percebe, sem serem pedidos.... "fico chateado, é
>> claro que fico chateado" (Gato Fedorento).
>>
>> Gostosão dos e-mails.... :-) essa é engraçada.
>
> Lol! Tiro meu chapéu pela sua tranquilidade.
>
> A propósito, não compreendi o ``dão conselhos a quem já percebe, sem
> serem pedidos...''. Parece uma diferença do uso de português --- você
> pode substituir o ``percebe'' por outra coisa?

Eu li o "já percebe" como "já compreende" ou "já sabe", ou ainda "já
conhece".

> Falando em português, seu acento grave em ``à mais de 4 anos'' encontra
> preposição e artigo onde não tem. O que tem ali é o verbo haver no
> sentido de tempo de decorrido.

--
Nuno Silva

Patricia Ferreira

unread,
Jan 14, 2024, 11:31:31 AM1/14/24
to
"Nuno Silva" <nunoj...@invalid.invalid> writes:

> On 2024-01-14, Patricia Ferreira wrote:
>
>> Daniel Cerqueira <dan....@brilhante.top> writes:
>>
>>> Patricia Ferreira <pfer...@example.com> writes:
>>>
>>>> Daniel Cerqueira <dan....@brilhante.top> writes:
> [...]
>>>>> Tenho email com domínio pessoal à mais de 4 anos, e estão a tentar
>>>>> ensinar-me sobre isso. Ridículo.
>>>>
>>>> Lol! Como a gente ia saber que você é o gostosão dos e-mails? Perdôe
>>>> nossa insolência.
>>>
>>> Dão conselhos a quem já percebe, sem serem pedidos.... "fico chateado, é
>>> claro que fico chateado" (Gato Fedorento).
>>>
>>> Gostosão dos e-mails.... :-) essa é engraçada.
>>
>> Lol! Tiro meu chapéu pela sua tranquilidade.
>>
>> A propósito, não compreendi o ``dão conselhos a quem já percebe, sem
>> serem pedidos...''. Parece uma diferença do uso de português --- você
>> pode substituir o ``percebe'' por outra coisa?
>
> Eu li o "já percebe" como "já compreende" ou "já sabe", ou ainda "já
> conhece".

Compreendi. É uma declaração contraditória dada que foi postada na
USENET. Por que alguém postaria qualquer coisa por aqui se não deseja
receber uma resposta? :-)

Patricia Ferreira

unread,
Jan 14, 2024, 11:33:14 AM1/14/24
to
Não estou usando qualquer software pra e-mail e criptografia. Todos
deveríamos conseguir extrair a chave pública acima, importá-la num
software e então encriptar alguma coisa (pra eu ler). Só transmiti uma
chave pública usando o formato PEM --- acima. ``PEM files are
essentially base64 encoded versions of the DER encoded data.'' DER é
uma codificação em binário. O que está escrito acima é essencialmente
uma estrutura

PublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
PublicKey BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}

Veja mais em, por exemplo,

https://mbed-tls.readthedocs.io/en/latest/kb/cryptography/asn1-key-structures-in-der-and-pem/#pem-files

Matematicamente, uma chave pública RSA é um par de números (n, e), sendo
n um módulo e o outro é um expoente, chamado de ``expoente público''.
(Existe o privado na chave privada.) Abaixo, o módulo está expresso em
base 16 (porque o número é grande), ignorando-se os dois pontos como
separador. O expoente é 37 em base 10, ou seja, 25 em base 16.) O
padrão que rege essa sintaxe é o X.509.

--8<---------------cut here---------------start------------->8---
%openssl.exe rsa -in pub.txt -pubin -text
writing RSA key
RSA Public-Key: (2048 bit)
Modulus:
00:d1:e4:e9:92:00:53:82:15:92:12:bf:14:b2:8a:
97:c9:36:9c:dc:2c:77:40:16:a5:fd:41:b9:c5:b3:
ff:ea:86:96:a3:d7:f7:bb:34:b9:b2:6b:f3:37:ab:
81:a2:98:de:0f:17:fb:62:a1:4b:99:77:88:aa:4d:
64:7c:17:74:a2:c1:61:32:11:67:1a:ab:0b:9d:f4:
3a:ab:e2:af:d2:a3:0c:39:af:5c:58:2d:95:e7:72:
b9:ca:84:37:12:8c:51:d6:42:49:f3:00:e6:b1:cf:
c3:8a:8e:d4:ab:3f:df:59:bd:6f:5c:8a:e3:ce:a0:
ae:c1:b1:c4:7a:ed:00:e1:ca:82:87:d1:96:75:c8:
14:b9:b6:f3:80:de:61:fd:23:4c:92:b5:a5:f6:78:
a4:cb:2c:6a:2b:bc:ce:8c:89:b7:e8:44:f9:02:0e:
1c:dd:9c:29:f7:0d:7e:c0:ca:71:cf:7f:6f:74:0b:
69:f3:69:27:42:e5:60:c8:1c:0a:4c:95:f8:53:5e:
4d:4d:68:5d:93:4f:6d:5c:8f:22:fd:ef:1d:26:d6:
57:93:c4:83:63:9a:d8:80:42:eb:c9:9b:de:70:f3:
07:e6:29:34:df:3f:bc:8b:4f:6f:ba:06:bf:21:e9:
69:67:ac:36:1a:6c:4c:db:4c:83:14:dc:c1:17:ce:
05:89
Exponent: 37 (0x25)
-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA0eTpkgBTghWSEr8UsoqX
yTac3Cx3QBal/UG5xbP/6oaWo9f3uzS5smvzN6uBopjeDxf7YqFLmXeIqk1kfBd0
osFhMhFnGqsLnfQ6q+Kv0qMMOa9cWC2V53K5yoQ3EoxR1kJJ8wDmsc/Dio7Uqz/f
Wb1vXIrjzqCuwbHEeu0A4cqCh9GWdcgUubbzgN5h/SNMkrWl9nikyyxqK7zOjIm3
6ET5Ag4c3Zwp9w1+wMpxz39vdAtp82knQuVgyBwKTJX4U15NTWhdk09tXI8i/e8d
JtZXk8SDY5rYgELryZvecPMH5ik03z+8i09vuga/IelpZ6w2GmxM20yDFNzBF84F
iQIBJQ==
-----END PUBLIC KEY-----
--8<---------------cut here---------------end--------------->8---

Daniel Cerqueira

unread,
Jan 14, 2024, 5:21:08 PM1/14/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Lol! Tiro meu chapéu pela sua tranquilidade.
>
> A propósito, não compreendi o ``dão conselhos a quem já percebe, sem
> serem pedidos...''. Parece uma diferença do uso de português --- você
> pode substituir o ``percebe'' por outra coisa?

Pode ficar ``dão conselhos sem serem pedidos'' ;-)

> Falando em português, seu acento grave em ``à mais de 4 anos'' encontra
> preposição e artigo onde não tem. O que tem ali é o verbo haver no
> sentido de tempo de decorrido.

É verdade. O meu cérebro já não é o que costumava ser. Dantes eu não
dava estes erros de ``à'' e ``há'' trocados... Tens razão.

Daniel Cerqueira

unread,
Jan 14, 2024, 5:25:52 PM1/14/24
to
O GnuPG só aceita chaves geradas pela norma OpenPGP. Não obtenho qualquer
erro, só diz "0 chaves importadas".
Deixa lá.

Patricia Ferreira

unread,
Jan 14, 2024, 10:32:30 PM1/14/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Lol! Tiro meu chapéu pela sua tranquilidade.
>>
>> A propósito, não compreendi o ``dão conselhos a quem já percebe, sem
>> serem pedidos...''. Parece uma diferença do uso de português --- você
>> pode substituir o ``percebe'' por outra coisa?
>
> Pode ficar ``dão conselhos sem serem pedidos'' ;-)

Legal. Mas o ``percebe'' é português típico? (Curiosidade.)

>> Falando em português, seu acento grave em ``à mais de 4 anos'' encontra
>> preposição e artigo onde não tem. O que tem ali é o verbo haver no
>> sentido de tempo de decorrido.
>
> É verdade. O meu cérebro já não é o que costumava ser.

E a nutrição? Mesma de sempre?

Patricia Ferreira

unread,
Jan 14, 2024, 10:32:31 PM1/14/24
to
Então é isso. Você pediu minha chave pública e ela está aí em cima. O
parsing da informação é trivial: basta ler de BEGIN a END, decodificar,
recodificar e importar. Nem os parênteses angulares de citação de
e-mail são um problema: eles não pertencem ao alfabeto da BASE 64. É
por isso que o cidadão mediano não usa essa criptografia de chave
pública via e-mail. Os chamados especialistas não têm um mínimo de
habilidade. Seu OpenPGP encontrará o que deseja no bloco a seguir.
(Knock yourself out.)

-----BEGIN PGP PUBLIC KEY BLOCK-----

mQGNBGWkmD4BDAC7/JAg6R5GuNXcN72un2nzzkNA0IZ1YEmsU7rdwUHjwHUlIO5D
ai2I3CLKKbIJkPKDqSqcreodAPYSlWTVeIPXQzltp4apDMKwANtdwBgop11+mcif
vjRIg2gX3cFOisCRjaH44N1pjWjIMVdULtRLmUwAQlEr1iaSGOaP8pQJltbdDdyx
Q/SNKZgIjg1rmedV1NB26w5YRppYJXEOH2mIciqnr0O5l9e5N3ESt3HVtqpUCU+r
PoDGAi6yMBw3AG4B/LdC5AvOsxH07SQ+8ypWAEc7vZiRg9iJfmksx2zqy6hL3yH4
3ZjctsODIbGBGZeGki6RYK/GfLKpXOVeVfmW3bEif28boJQFqcStyg+Yd2ZDZ60d
1Nd+lFZMuoYJtO8/YKKZIVpXBwiSbNRFWU52H5wesIk6uek78hCwaP2k6NFIWW+3
0fSjCog9u6OGFg6/7XcR/QtOLRi6b/x5zBwd/vTkxB5fRKWlBZYEnXymAY6VHAVi
aOCT7wuMyeWpNvMAEQEAAbQoUGF0cmljaWEgRmVycmVpcmEgPHBhdHJpY2lhQGV4
YW1wbGUuY29tPokB1AQTAQgAPhYhBB3azkN1pIPYYlAH4ZDwloddOF/VBQJlpJg+
AhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEJDwloddOF/VNnEL
/3p34gbhWXPQ9Qx03wsXdZ8NI97sI4qwAWPfLl+s1piQ5rDcDgaVNTYpCcs7HIft
QPuHvI6VyP+AcRRGMu8eQlvHk5jIWnfYq6aL71gcRykqBowRsqQU2vizoUU44y7j
c3MMSMfSRfn3Qpj1HSvuRc933/6HJzv4S0We85B4kwCjHM90LZstJr0T4bLijoTi
rZVlc1L94mAnOl0DHC/HdZObvYcPdlXXUEO0hHGueBRWv9x7jsoITK0hhc64fRkS
/pKNlykcvS57a2B8RU9zFS3fiW/m3iqavHmegw/setZK3Xe5hF1mizY56roKNoGn
4P1brY8KGJuURJDgokkGpulqO5wqhQvm87RU2aPiFvvwzkYrMlj+oT2Wq8InkwBn
q6rTCE1Rd8c99U5KBiNDszNy7hP+pBZyuwTERHXqR2acyLm9R2LgPk++y2hoU2WP
P9OuQu9gX3mMPqqBhjgl8nm+lEPTTK+YvJkXOyE2NKMeUHlx0eUM1ze8kToY8f9p
ELkBjQRlpJg+AQwAyW+p352yAfLwd1eWlUBdHeJh5t58QupjzuDZA0FcGmvtCUik
WuaqI6rWDu7cF9wncGpjLPepb2zqYZ8w2jqUKGotg/bF63vlPkg7tg7PpCjr9bAn
2OoUBBSJPck56Ya+Y6I+3HQVsGzfDGzfhxFE/d3oz00KKyPhctOFjDZOfSIy+111
WCDcRxA87oR/8vHetoTtILDLydLVrZtwEf3jbEiTFewp6vKRRc1VIf1l7LALwMO3
w8SH3zfjYIy8Cmz/z7MKohBPp8aiAfhESHw5TsLPIrnho9qz60bVMg1wRNKmpE3a
VESlHjs9RUwprFGmB1WJQSN4cKyLqpSLlVjM6BF6shXhDSpnaEka8iVk/6yxM04s
LmzY98knGIMOC12I0bm0XVwHThoHTl+6gwz5m1JBauykxFLoapFM4SbQssVfdANp
ag4ZcT7YRbsXaoG5myXTZ8wmapXu5Eb88MmmEaDzdM3/DKaOswPYk4B4yTe4x65J
ncNPSP+1U8Lt5BDBABEBAAGJAbwEGAEIACYWIQQd2s5DdaSD2GJQB+GQ8JaHXThf
1QUCZaSYPgIbDAUJA8JnAAAKCRCQ8JaHXThf1cvdDACqYTVbPXs8YXpPxrEG0M1c
Eobn6G3fXKNyJlGKwlNUEgS3/ipJmVDNpyLkXHjW25sLYtk517dkRJs7BBqxc6IA
Ao3T/NEmiexIQocnF7wD33O8JXzqCxz9+OrF8ehpMtJxuAIFbzmPzpl2tZyHzMQG
ACp9T6is7kxhYERcBpWJfnjhyPGXnA3ULgz0BTDWK0pXZMXiKU47/0qd+6phUOAp
r6cSxvJxBb9K+1zvFeGX967nQR5NzgFQF/ocD1h4CzfG6b6PIz/BjYlqcmdkAmHs
3xlfJRvH1Dw8qDWn/CnjSVSn1hTKlejpFC6n16IAlLDEASr0WWstj4DYpHT3PLmY
3oY0N01CZ6LDTTbgT7QVTZ3ENCzwIrTSfFsFcAXdgrsJJkTAZsAYEKqODNOnZ1uD
lh95OLT2RWwSRUr+Yz2w4qutahbefoKhmRK233nVz8p4Uhxf06XFd5/oizbqtELi
q3edzP/QdaFYkIZm361YDzl62mRGiqSmzNEOBOk72iw=
=KA/c
-----END PGP PUBLIC KEY BLOCK-----

Daniel Cerqueira

unread,
Jan 15, 2024, 10:23:52 AM1/15/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> Patricia Ferreira <pfer...@example.com> writes:
>>
>>> Lol! Tiro meu chapéu pela sua tranquilidade.
>>>
>>> A propósito, não compreendi o ``dão conselhos a quem já percebe, sem
>>> serem pedidos...''. Parece uma diferença do uso de português --- você
>>> pode substituir o ``percebe'' por outra coisa?
>>
>> Pode ficar ``dão conselhos sem serem pedidos'' ;-)
>
> Legal. Mas o ``percebe'' é português típico? (Curiosidade.)

"Perceber" é sinónimo de "entender". É Português típico. "Perceber" de
percepção, que é necessário para haver o entendimento.

>>> Falando em português, seu acento grave em ``à mais de 4 anos'' encontra
>>> preposição e artigo onde não tem. O que tem ali é o verbo haver no
>>> sentido de tempo de decorrido.
>>
>> É verdade. O meu cérebro já não é o que costumava ser.
>
> E a nutrição? Mesma de sempre?

Ohh, não quero muito falar disso. Há 5 anos que mudei para uma nutrição
páleo.

Daniel Cerqueira

unread,
Jan 15, 2024, 10:43:09 AM1/15/24
to
Está-me a faltar uma mensagem. Não a encontro. Vou responder assim, aqui.

Se é para apenas usar uma função recursiva, com as funções primitivas de
Lisp, parece-me mais díficil.

Principalmente porque:

(find-path 'C 'D sample-graph) produz '(C D) e não '((C D))

(find-path 'E 'D sample-graph) produz '((E F D) (E C D)) e não
'((E C D) (E F D))

Outra pergunta:
O segundo argumento de /find-path/ tem de sempre ter os vértices como
NIL? Para este grafo, só o 'D e o 'G podem ficar no segundo argumento?

Consegues dar mais exemplos, para além de:

(find-path 'C 'D sample-graph) produza '(C D)
(find-path 'E 'D sample-graph) produza '((E F D) (E C D))
(find-path 'C 'G sample-graph) produza nil

?

Patricia Ferreira

unread,
Jan 15, 2024, 12:00:58 PM1/15/24
to
É mais difícil. (Estamos fazendo um diagnóstico.)

> Principalmente porque:
>
> (find-path 'C 'D sample-graph) produz '(C D) e não '((C D))

Pode assumir que seja '((C D)) porque é trivial transformá-la pra
definição do problema. (O objetivo do exercício não está aí.) (Um
segundo procedimento colapsa listas unitárias pro /car/ delas.)

> (find-path 'E 'D sample-graph) produz '((E F D) (E C D)) e não
> '((E C D) (E F D))

Okay, façamos uma simplificação então. Faça com que find-path encontre
apenas um caminho entre os vértices, ou seja, ou ela produz (E F D) ou
ela produz (E C D) para /sample-graph/.

Mais fácil assim.

> Outra pergunta:
> O segundo argumento de /find-path/ tem de sempre ter os vértices como
> NIL? Para este grafo, só o 'D e o 'G podem ficar no segundo argumento?

O segundo argumento é um vértice de destino. Qualquer destino pode
entrar lá. Se o caminho não existir, /find-path/ produz nil. (Se o
destino nem existir, pode retornar nil também, mas pode assumir que
origem e destino sempre existem.)

> Consegues dar mais exemplos, para além de:
>
> (find-path 'C 'D sample-graph) produza '(C D)
> (find-path 'E 'D sample-graph) produza '((E F D) (E C D))
> (find-path 'C 'G sample-graph) produza nil
>
> ?

(find-path 'C 'D sample-graph) produza '(C D)
(find-path 'E 'D sample-graph) produza (or '(E F D) '(E C D))
(find-path 'C 'G sample-graph) produza nil
(find-path 'A 'D sample-graph) produza
(or '(A B F G) (A B E F G) (A E F G))
(find-path 'A 'Z sample-graph) produza nil
(find-path 'Z 'B sample-graph) produza nil

Pode assumir que origem e destino sempre existem. (Ignore exemplos como
os dois últimos, A -> Z e Z -> B.)

Nuno Silva

unread,
Jan 16, 2024, 9:04:31 AM1/16/24
to
On 2024-01-12, Daniel Cerqueira wrote:

> Ninguém <use...@rasparta.org> writes:
>
>> Daniel Cerqueira (dan....@brilhante.top) escreveu no dia 2024-01-11
>> (Thursday), cerca das 16:42 +0000:
>>
>> Não entendendo lisp, por exemplo, colocar uma data de "tralha que não
>> sei o que faz só porque tem o efeito que eu pretendo" no ficheiro de
>> configuração pode resolver-me o problema de utilização, mas não o de
>> ignorância.
>> Acho que a metodologia que a Patrícia sempre sugere talvez seja melhor
>> - ler um bom livro sobre o assunto - pelo menos até entender o mínimo
>> para ser perigoso, depois então, ok, ir arriscando um bocadinho.
>
> Apoio essa metodologia. Eu também sou assim.
>
> Uma ótima coisa no Emacs, é que podes aprender sobre o Emacs usando o
> Emacs. Bootstrapping knowleadge :-) Por exemplo, tens o tutorial do
> Emacs dentro do Emacs. Podes aceder ao tutorial usando C-h t (isto é,
> Control pressionada mais a tecla h, largar o Control e carregar na tecla
> t). Também tens o C-h C-h (isto é, Control pressionado e duas vezes a
> tecla h) que é como obténs ajuda sobre a ajuda do Emacs.

A ajuda interactiva do Emacs é capaz de ser dos melhores sistemas de
ajuda que já conheci até ao momento.

Recomendo F1 f e F1 v para ver a documentação de funções e variávis (e
a prompt para escrever o nome da função/variável permite não só
completar o resto do nome e ver o que existe com o prefixo introduzido,
mas também preencher segmentos intermédios (em vez de só no fim do que
foi escrito), o que ajuda a descobrir mais algumas coisas).

Escrevendo algo como "inicio--fim", e fazendo de seguida C-i/tab, o
minibuffer vai encontrar inicio-a-fim e inicio-b-fim-c, por exemplo
(assumindo que essas funções ou variáveis existem, claro). Isto pode
ser uma forma interessante de descobrir funções e variáveis.

(Talvez isto dependa da versão do GNU Emacs? Tenho observado este
comportamento há bastante tempo, mas sem ir investigar não sei há
quanto tempo é assim.)

(F1 ou C-h deverá ir dar ao mesmo em muitos casos, eu é que aqui do
meu lado evito o C-h porque a inicialização para o terminal faz com
que C-h deixe de funcionar pelo menos nalguns casos, e uso sempre F1
para evitar surpresas.)


--
Nuno Silva

Patricia Ferreira

unread,
Jan 16, 2024, 9:45:23 AM1/16/24
to
"Nuno Silva" <nunoj...@invalid.invalid> writes:

[...]

> A ajuda interactiva do Emacs é capaz de ser dos melhores sistemas de
> ajuda que já conheci até ao momento.
>
> Recomendo F1 f e F1 v para ver a documentação de funções e variávis (e
> a prompt para escrever o nome da função/variável permite não só
> completar o resto do nome e ver o que existe com o prefixo introduzido,
> mas também preencher segmentos intermédios (em vez de só no fim do que
> foi escrito), o que ajuda a descobrir mais algumas coisas).
>
> Escrevendo algo como "inicio--fim", e fazendo de seguida C-i/tab, o
> minibuffer vai encontrar inicio-a-fim e inicio-b-fim-c, por exemplo
> (assumindo que essas funções ou variáveis existem, claro). Isto pode
> ser uma forma interessante de descobrir funções e variáveis.
>
> (Talvez isto dependa da versão do GNU Emacs? Tenho observado este
> comportamento há bastante tempo, mas sem ir investigar não sei há
> quanto tempo é assim.)

É o padrão, assim como C-h.

Daniel Cerqueira

unread,
Jan 16, 2024, 1:10:07 PM1/16/24
to
Mesmo assim. Não estou a ver maneira de isso ser possível, dado eu só
poder fazer uma função, com o cond, car, cdr, eq, atom, cons, etc..

Não consigo fazer tal função.

Tem uma solução? Qual é?

Patricia Ferreira

unread,
Jan 16, 2024, 8:06:20 PM1/16/24
to
Você pode (e deve) fazer várias funções.

> Não consigo fazer tal função.

Não é muito fácil. Isso é ensinado no HtDP. O propósito dos exercícios
é diagnosticar isso. Devemos ler o livro ou não? Parece que devemos.

Você pode olhar a solução deles, capítulo 29, parte V. Mas não creio
que você aprecie muito a apresentação deles se você não estiver bem
treinado no método de raciocínio que eles usam.

Uma sugestão é a gente voltar um pouco e trabalhar num exercício mais
fácil. Por exemplo, capítulo 19, parte IV, exercício 313 --- tendo lido
o capítulo 19 todo, o que não demora. Está bem relacionado com
/find-path/, mas é mais fácil. O próprio avisa isso no capítulo 29.

Ou então insistimos em /find-path/, o que não recomendo. Diga-me o que
pensas.

Daniel Cerqueira

unread,
Jan 17, 2024, 9:10:57 AM1/17/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> Mesmo assim. Não estou a ver maneira de isso ser possível, dado eu só
>> poder fazer uma função, com o cond, car, cdr, eq, atom, cons, etc..
>
> Você pode (e deve) fazer várias funções.
>
>> Não consigo fazer tal função.

Eu tinhas perguntado se era para usar /uma/ função recursiva. Se posso
usar mais que uma função, talvez consiga.

Vou tentar resolver isto, nestes próximos dias. De momento, não estou
com disponibilidade; é só esperar um pouquinho.

> Não é muito fácil. Isso é ensinado no HtDP. O propósito dos exercícios
> é diagnosticar isso. Devemos ler o livro ou não? Parece que devemos.
>
> Você pode olhar a solução deles, capítulo 29, parte V. Mas não creio
> que você aprecie muito a apresentação deles se você não estiver bem
> treinado no método de raciocínio que eles usam.
>
> Uma sugestão é a gente voltar um pouco e trabalhar num exercício mais
> fácil. Por exemplo, capítulo 19, parte IV, exercício 313 --- tendo lido
> o capítulo 19 todo, o que não demora. Está bem relacionado com
> /find-path/, mas é mais fácil. O próprio avisa isso no capítulo 29.
>
> Ou então insistimos em /find-path/, o que não recomendo. Diga-me o que
> pensas.

No HtDP usa-se Common Lisp? Lisp 1.5? Scheme?

Como ficaste a conhecer esse livro?

Daniel Cerqueira

unread,
Jan 17, 2024, 10:51:55 AM1/17/24
to
Demorei à volta de 40 minutos.

Aqui está a minha resposta, assim, sem querer pensar muito mais no
assunto: (Não consultei esse livro online.)

(defun get-start-list (start graph)
(cond
((null graph) nil)
((eq (caar graph) start) (car graph))
(t (get-start-list start (cdr graph)))))

(defun get-path-list (start end graph)
(cond
((null start) (cons nil nil))
((eq start end) (cons end nil))
((eq (car (get-start-list start graph)) start)
(cons
start
(get-path-list (caadr (get-start-list start graph)) end graph)))))

(defun find-path (start end graph)
(cond
((null (car (last (get-path-list start end graph)))) nil)
(t (get-path-list start end graph))))

Dá-me o teu parecer ;-)

Patricia Ferreira

unread,
Jan 18, 2024, 6:29:09 AM1/18/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Daniel Cerqueira <dan....@brilhante.top> writes:
>>
>>> Mesmo assim. Não estou a ver maneira de isso ser possível, dado eu só
>>> poder fazer uma função, com o cond, car, cdr, eq, atom, cons, etc..
>>
>> Você pode (e deve) fazer várias funções.
>>
>>> Não consigo fazer tal função.
>
> Eu tinhas perguntado se era para usar /uma/ função recursiva. Se posso
> usar mais que uma função, talvez consiga.

Use o que você quiser --- incluindo qualquer linguagem também.

> Vou tentar resolver isto, nestes próximos dias. De momento, não estou
> com disponibilidade; é só esperar um pouquinho.

Sempre pressa alguma.

>> Não é muito fácil. Isso é ensinado no HtDP. O propósito dos exercícios
>> é diagnosticar isso. Devemos ler o livro ou não? Parece que devemos.
>>
>> Você pode olhar a solução deles, capítulo 29, parte V. Mas não creio
>> que você aprecie muito a apresentação deles se você não estiver bem
>> treinado no método de raciocínio que eles usam.
>>
>> Uma sugestão é a gente voltar um pouco e trabalhar num exercício mais
>> fácil. Por exemplo, capítulo 19, parte IV, exercício 313 --- tendo lido
>> o capítulo 19 todo, o que não demora. Está bem relacionado com
>> /find-path/, mas é mais fácil. O próprio avisa isso no capítulo 29.
>>
>> Ou então insistimos em /find-path/, o que não recomendo. Diga-me o que
>> pensas.
>
> No HtDP usa-se Common Lisp? Lisp 1.5? Scheme?

Eles usam as teaching languages BSL, BSL+, ISL, ISL+ e ASL. Beginning
Student Language, BSL com abreviações, Intermediate ..., ..., Advanced
....

> Como ficaste a conhecer esse livro?

Interessei-me por Lisp vendo pessoas na USENET usando Lisp --- Barry
Margolin especificamente chamou-me a atenção --- e fazendo coisas
maravilhosas que as linguagens ``modernas'' não conseguiam fazer.
Entendi que havia muitos dialetos de Lisp. Escolhi Scheme e passei a
usar PLT Scheme. Vida difícil. Vi que não entendia nada de
programação. Mal conseguia entender a documentação de PLT Scheme
especificamente. Descobri eventualmente que o HtDP existia. Resolvi
lê-lo pra adquirir um vocabulário que pudesse me ajudar a ler a
documentação --- os autores do HtDP são autores de PLT Scheme, isto é,
Racket. E foi aí que descobri que o livro era interessante. Ajudou
muito, mas a documentação como um todo ainda fala de um mundo que o HtDP
não aborda --- que é o mundo Racket. O HtDP é sobre o design de
programas, de procedimentos. Não é sobre o mundo Racket.

Patricia Ferreira

unread,
Jan 18, 2024, 6:29:25 AM1/18/24
to
Desculpe a demora --- o assunto aqui exige tempo e energia.

Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Daniel Cerqueira <dan....@brilhante.top> writes:
>>
>>> Mesmo assim. Não estou a ver maneira de isso ser possível, dado eu só
>>> poder fazer uma função, com o cond, car, cdr, eq, atom, cons, etc..
>>
>> Você pode (e deve) fazer várias funções.
>>
>>> Não consigo fazer tal função.
>>
>> Não é muito fácil. Isso é ensinado no HtDP. O propósito dos exercícios
>> é diagnosticar isso. Devemos ler o livro ou não? Parece que devemos.
>>
>> Você pode olhar a solução deles, capítulo 29, parte V. Mas não creio
>> que você aprecie muito a apresentação deles se você não estiver bem
>> treinado no método de raciocínio que eles usam.
>>
>> Uma sugestão é a gente voltar um pouco e trabalhar num exercício mais
>> fácil. Por exemplo, capítulo 19, parte IV, exercício 313 --- tendo lido
>> o capítulo 19 todo, o que não demora. Está bem relacionado com
>> /find-path/, mas é mais fácil. O próprio avisa isso no capítulo 29.
>>
>> Ou então insistimos em /find-path/, o que não recomendo. Diga-me o que
>> pensas.
>
> Demorei à volta de 40 minutos.

O tempo sugere que esse é um problema que você não resolveu ainda. Você
está tentando expressar essa estratégia pela primeira vez.

> Aqui está a minha resposta, assim, sem querer pensar muito mais no
> assunto: (Não consultei esse livro online.)
>
> (defun get-start-list (start graph)
> (cond
> ((null graph) nil)
> ((eq (caar graph) start) (car graph))
> (t (get-start-list start (cdr graph)))))

Uma sugestão é chamar essa de get-vertex or alguma coisa assim.
Maravilha que você a implementou por conta própria --- você deve saber
que /assoc/ em Common Lisp faria o mesmo por você aí.

> (defun get-path-list (start end graph)
> (cond
> ((null start) (cons nil nil))
> ((eq start end) (cons end nil))
> ((eq (car (get-start-list start graph)) start)
> (cons
> start
> (get-path-list (caadr (get-start-list start graph)) end graph)))))

Maravilha de procedimento. Esse aí já é quase uma solução. Ele só não
é uma solução porque ele desiste no primeiro caminho que tenta.

> (defun find-path (start end graph)
> (cond
> ((null (car (last (get-path-list start end graph)))) nil)
> (t (get-path-list start end graph))))
>
> Dá-me o teu parecer ;-)

Você deve saber que sua solução não computa a resposta desejada. A
impressão que dá é que você olhou só os casos mais simples que colocamos
como teste. Por exemplo, você computa a resposta certa em

--8<---------------cut here---------------start------------->8---
CL-USER> (find-path 'C 'D sample-graph)
((C D))
--8<---------------cut here---------------end--------------->8---

Computa a resposta certa em

--8<---------------cut here---------------start------------->8---
CL-USER> (find-path 'C 'A sample-graph)
NIL
--8<---------------cut here---------------end--------------->8---

Mas dá uma olhada em

--8<---------------cut here---------------start------------->8---
CL-USER> (find-path 'A 'E sample-graph)
((A E))
--8<---------------cut here---------------end--------------->8---

Fica faltando aí (A B E). Seu advogado objeta e diz que a gente
permitiu qualquer caminho pro destino e não todos --- mas seu
procedimento responde uma lista, o que sugere que ele está em busca de
todos, o que fica claro em

--8<---------------cut here---------------start------------->8---
CL-USER> (find-path 'A 'F sample-graph)
((A (B F)) (A (E F)))
--8<---------------cut here---------------end--------------->8---

sendo que a forma da resposta mudou. O resultado que esperávamos era

((A B F) (A B E F) (A E F))

embora não exatamente nessa ordem --- qualquer ordem serve. Então
afirmo que não temos uma solução aí.

--8<---------------cut here---------------start------------->8---
De qualquer forma, dou-lhe os parabéns pela tentativa e um diagnóstico
final. O diagnóstico é de que o HtDP --- pelo menos em suas partes
posteriores do livro --- contém técnicas que não dominamos nem de perto.
Agora, um problema que vejo aqui é que possivelmente se você resolver
ler só as partes posteriores do livro, talvez você não compreenda o
processo de escrita que eles recomendam lá. É o aviso. O livro é um
jeito de pensar que exige um hábito de pensar.
--8<---------------cut here---------------end--------------->8---

(*) Seu find-path

Okay, uma pergunta é --- onde está a falha no find-path? Ou, melhor,
por que seu procedimento não funciona? Ou melhor, qual é a essência da
sua estratégia?

Sua estratégia parece bem clara na sua escrita --- e parabéns pela
clareza de escrita (com o devido agradecimento à cultura Lisp, o que
você parece ter). Você afirma que se eu descer num certo caminho e
terminar com NIL, então é porque aquele caminho é sem saída --- desista
dele. De outra forma, você responde o caminho. Isso sugere que
get-path-list é de fato o seu descobridor de caminhos e find-path é seu
detector de caminhos válidos. Mas essas observações são contraditórias.
Se get-path-list é o seu descobridor de caminhos, por que ela tenta
coletar mais de um caminho? Quando leio find-path, minha conclusão é de
que sua solução reportaria um único caminho válido, o que não é o que
acontece em

--8<---------------cut here---------------start------------->8---
CL-USER> (find-path 'A 'F sample-graph)
((A (B F)) (A (E F)))
--8<---------------cut here---------------end--------------->8---

Daniel Cerqueira

unread,
Jan 18, 2024, 12:57:56 PM1/18/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Desculpe a demora --- o assunto aqui exige tempo e energia.

Está tranquila. Até que não achei te tivesses demorado muito tempo.

> Você deve saber que sua solução não computa a resposta desejada. A
> impressão que dá é que você olhou só os casos mais simples que colocamos
> como teste. Por exemplo, você computa a resposta certa em
>
> --8<---------------cut here---------------start------------->8---
> CL-USER> (find-path 'C 'D sample-graph)
> ((C D))
> --8<---------------cut here---------------end--------------->8---

A mim, não me dá assim:

--8<---------------cut here---------------start------------->8---
(find-path 'c 'd sample-graph)
(C D)
--8<---------------cut here---------------end--------------->8---

> Computa a resposta certa em
>
> --8<---------------cut here---------------start------------->8---
> CL-USER> (find-path 'C 'A sample-graph)
> NIL
> --8<---------------cut here---------------end--------------->8---

--8<---------------cut here---------------start------------->8---
(find-path 'c 'a sample-graph)
NIL
--8<---------------cut here---------------end--------------->8---

> Mas dá uma olhada em
>
> --8<---------------cut here---------------start------------->8---
> CL-USER> (find-path 'A 'E sample-graph)
> ((A E))
> --8<---------------cut here---------------end--------------->8---

--8<---------------cut here---------------start------------->8---
(find-path 'a 'e sample-graph)
(A B E)
--8<---------------cut here---------------end--------------->8---

> Fica faltando aí (A B E). Seu advogado objeta e diz que a gente
> permitiu qualquer caminho pro destino e não todos --- mas seu
> procedimento responde uma lista, o que sugere que ele está em busca de
> todos, o que fica claro em
>
> --8<---------------cut here---------------start------------->8---
> CL-USER> (find-path 'A 'F sample-graph)
> ((A (B F)) (A (E F)))
> --8<---------------cut here---------------end--------------->8---

--8<---------------cut here---------------start------------->8---
(find-path 'a 'f sample-graph)
NIL
--8<---------------cut here---------------end--------------->8---

De certeza que estavas a usar o mey código que te enviei? Esses
resultados parecer ser de outro código.

De qualquer das maneiras, o este meu código não está a funcionar
direito, em alguns casos.

Daniel Cerqueira

unread,
Jan 18, 2024, 1:03:17 PM1/18/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> No HtDP usa-se Common Lisp? Lisp 1.5? Scheme?
>
> Eles usam as teaching languages BSL, BSL+, ISL, ISL+ e ASL. Beginning
> Student Language, BSL com abreviações, Intermediate ..., ..., Advanced

Essas linguagens devem ser de pseudo-código. Eu prefiro aprender em
linguagens mesmo "verdadeiras".

>> Como ficaste a conhecer esse livro?
>
> Interessei-me por Lisp vendo pessoas na USENET usando Lisp --- Barry
> Margolin especificamente chamou-me a atenção --- e fazendo coisas
> maravilhosas que as linguagens ``modernas'' não conseguiam fazer.
> Entendi que havia muitos dialetos de Lisp. Escolhi Scheme e passei a
> usar PLT Scheme. Vida difícil. Vi que não entendia nada de
> programação. Mal conseguia entender a documentação de PLT Scheme
> especificamente. Descobri eventualmente que o HtDP existia. Resolvi
> lê-lo pra adquirir um vocabulário que pudesse me ajudar a ler a
> documentação --- os autores do HtDP são autores de PLT Scheme, isto é,
> Racket. E foi aí que descobri que o livro era interessante. Ajudou
> muito, mas a documentação como um todo ainda fala de um mundo que o HtDP
> não aborda --- que é o mundo Racket. O HtDP é sobre o design de
> programas, de procedimentos. Não é sobre o mundo Racket.

Então o HtDP é feito por pessoas de Racket. O livro aplica-se a qualquer
Lisp (como o Common Lisp) ?

Patricia Ferreira

unread,
Jan 18, 2024, 1:09:08 PM1/18/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

[...]

> De certeza que estavas a usar o mey código que te enviei? Esses
> resultados parecer ser de outro código.

Perdão. Modifiquei seu código e não consegui retorná-lo ao estado
original (como pensei).

> De qualquer das maneiras, o este meu código não está a funcionar
> direito, em alguns casos.

Pois é. Sua estratégia é realmente expressa por get-path-list. O
procedimento find-path é apenas um procedimento de apresentação --- se
get-path-list não encontrar o caminho, diga nil.

O que há de errado com sua estratégia? Façamos a pergunta --- por que
get-path-list não encontra o caminho de F a G? São vizinhos; deveria
ser trivial. Mas G não é o /primeiro/ vizinho de F. O primeiro vizinho
de F é D. Como não há caminho entre D e G, seu procedimento pensa que
não há caminho. Em outras palavras, seu procedimento só faz uma
tentativa de várias possíveis --- se não houver caminho na primeira, seu
procedimento acha que não há caminho qualquer.

Patricia Ferreira

unread,
Jan 18, 2024, 1:47:36 PM1/18/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

> Patricia Ferreira <pfer...@example.com> writes:
>
>> Daniel Cerqueira <dan....@brilhante.top> writes:
>>
>>> No HtDP usa-se Common Lisp? Lisp 1.5? Scheme?
>>
>> Eles usam as teaching languages BSL, BSL+, ISL, ISL+ e ASL. Beginning
>> Student Language, BSL com abreviações, Intermediate ..., ..., Advanced
>
> Essas linguagens devem ser de pseudo-código.

Não é o caso.

> Eu prefiro aprender em linguagens mesmo "verdadeiras".

O livro não sabe que ferramenta você usa.

>>> Como ficaste a conhecer esse livro?
>>
>> Interessei-me por Lisp vendo pessoas na USENET usando Lisp --- Barry
>> Margolin especificamente chamou-me a atenção --- e fazendo coisas
>> maravilhosas que as linguagens ``modernas'' não conseguiam fazer.
>> Entendi que havia muitos dialetos de Lisp. Escolhi Scheme e passei a
>> usar PLT Scheme. Vida difícil. Vi que não entendia nada de
>> programação. Mal conseguia entender a documentação de PLT Scheme
>> especificamente. Descobri eventualmente que o HtDP existia. Resolvi
>> lê-lo pra adquirir um vocabulário que pudesse me ajudar a ler a
>> documentação --- os autores do HtDP são autores de PLT Scheme, isto é,
>> Racket. E foi aí que descobri que o livro era interessante. Ajudou
>> muito, mas a documentação como um todo ainda fala de um mundo que o HtDP
>> não aborda --- que é o mundo Racket. O HtDP é sobre o design de
>> programas, de procedimentos. Não é sobre o mundo Racket.
>
> Então o HtDP é feito por pessoas de Racket. O livro aplica-se a qualquer
> Lisp (como o Common Lisp) ?

O livro se aplica a não-programadores, embora provavelmente só
reconheceria o fato quem for um não-programador em certas esferas da
vida e um programador em outras. De uma forma geral, pra saber do que
se trata um livro, é *realmente* preciso lê-lo. O HtDP não consegue
transmitir do que ele se trata através de resumos. Por isso ignorei-o
por tanto tempo. Sorte a minha que achei que ele poderia me ajudar com
vocabulário --- e aí descobri o conteúdo.

Não é uma recomendação de leitura. Estou apenas diagnosticando. O HtDP
evidentemente tem coisas a oferecer a você. Também não é uma
recomendação a Racket --- ao contrário. Desisti de Racket. Common Lisp
me parece muito mais divertida de se usar.

Sobre Common Lisp especificamente, já conversamos --- ANSI Common Lisp é
uma descrição da linguagem que deve ser completa ou próxima de completa
e é direta ao ponto --- pra programadores.

Daniel Cerqueira

unread,
Jan 18, 2024, 2:24:54 PM1/18/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> De qualquer das maneiras, o este meu código não está a funcionar
>> direito, em alguns casos.
>
> Pois é. Sua estratégia é realmente expressa por get-path-list. O
> procedimento find-path é apenas um procedimento de apresentação --- se
> get-path-list não encontrar o caminho, diga nil.
>
> O que há de errado com sua estratégia? Façamos a pergunta --- por que
> get-path-list não encontra o caminho de F a G? São vizinhos; deveria
> ser trivial. Mas G não é o /primeiro/ vizinho de F. O primeiro vizinho
> de F é D. Como não há caminho entre D e G, seu procedimento pensa que
> não há caminho. Em outras palavras, seu procedimento só faz uma
> tentativa de várias possíveis --- se não houver caminho na primeira, seu
> procedimento acha que não há caminho qualquer.

Pois... eu sei que só está a resolver o primeiro caminho. Quando tento
fazer com que resolva todos os caminhos, o meu código fica muito
complicado; e ainda não consegui fazê-lo. Estava apenas a tentar usar
cons e isso estava-me a dificultar um pouco.

Acho que a essência deste exercício está-me a passar ao lado.

Como resolverias este exercício? :-)

Patricia Ferreira

unread,
Jan 18, 2024, 3:56:13 PM1/18/24
to
Eis uma tentativa pela receita HtDP. Um Vértice é um Símbolo. Um
Vizinhos é uma lista de Símbolos. Um Grafo é um de

- NIL
- (cons Vértice Vizinhos)

Por exemplo,

NIL ou (list B E))

são Vizinhos. Já A, B, C, ... são Vértices. E, assim,

((A (B E))
(B (E F)))

é um grafo. Precisamos de um procedimento neighbors que extrai os
Vizinhos de um vértice. Como é trivial, usemos /assoc/:

(defun neighbors (v g) (assoc v g))

Como já temos Grafo e Vértice, já podemos escrever a assinatura de
find-path. Ela consome dois vértices e um grafo e produz uma lista de
Vértice --- que é o caminho em si.

Vértice Vértice Grafo --> List-of Vértices

Usando sample-graph, temos os exemplos:

(find-path 'C 'D sample-graph) --> (C D)
(find-path 'E 'D sample-graph) --> (E C D) ou (E F D)
(find-path 'C 'G sample-graph) --> sem-caminho

O caso E--D já apresenta essa ambiguidade: tem dois caminhos possíveis.
O caso C--G não tem nenhum. É preciso decidir o que fazer em cada caso.
Dizer NIL quando sem-caminho vai ajudar a escrever um código mais curto
em Common Lisp. Quanto à ambiguidade, escolhamos por ora o primeiro
caminho que for encontrado.

O procedimento find-path tem que retornar uma List-of Vértices, então
não estamos incorretos se retornarmos NIL num esboço

(defun find-path (src dst g)
NIL)

A receita pra esse tipo de problema é considerar algumas possibilidades:
o caso base, o repartir do problema em um subproblema e o passo de
combinação da subsolução pra obter o problema original.

Quando dois Vértices são vizinhos, o caminho é trivial: os dois vértices
numa lista. Mas dá pra tornar esse problema ainda mais trivial que é
quando os dois Vértices são o mesmo Vértice, que é o que você fez em
get-path-list. Usemos isso também: a resposta aí é (cond end nil).

Se os argumentos são diferentes, precisamos considerar cada vizinho.
Considerar cada vizinho é um problema novo, mas /cada um/ desses
problemas é da mesma forma que o problema original. Se os vizinhos de
/src/ são v1, v2, então os subproblemas são

(find-path v1 end g)
(find-path v2 end g)

Agora, invocar a resolução desses subproblemas é um problema /novo/
porque envolve uma List-of Vértices. Esse /tipo/ diferente nos leva a
escrever um novo procedimento --- porque as assinaturas não casam. Que
tipo de resposta esse novo procedimento produz? Uma List-of Vértices,
logo NIL é um esboço de resposta.

;; Vizinhos Vértice Grafo --> List-of Vértice
;; interpretação: o primeiro caminho encontrado entre um Vértice de
;; origem (em Vizinhos) até o Vértice de destino no Grafo.
(defun find-path/list (ns dst g)
NIL)

Agora já podemos escrever find-path, assumindo que find-path/list está
pronta. Se houver um caminho de algum vizinho até DST, então a resposta
é uma lista não-vazia. Se não houver, é NIL. Assim, se find-path/list
retorna NIL, então não há caminho algum. Se ela retorna List-of
Vértice, então a resposta do problema original é

(cons SRC <RETORNO DE FIND-PATH/LIST).

(defun find-path (src dst graph)
(cond
((eq src dst) (cons src nil))
(t
(let ((subsolution (find-path/list (neighbors src graph) dst graph)))
(if subsolution
(cons src subsolution)
nil)))))

Recapitule. Se SRC e DST são idênticos, caso base. Se forem
diferentes, então precisamos ver se existe caminho entre os vizinhos de
SRC até DST. Isso quem descobre é find-path/list. Se find-path/list
retornar uma coisa que não é NIL, então a solução do problema original é
simplesmente SRC na cabeça de SUBSOLUTION. Se não houver, então
respondemos NIL também.

Pra isso funcionar, só precisamos de find-path/list. É hora de recordar
o projeto que fizemos pra find-path/list, o que repetimos aqui pra não
ter que recuperar texto acima já passado.

;; Vizinhos Vértice Grafo --> List-of Vértice
;; interpretação: o primeiro caminho encontrado entre um Vértice de
;; origem (em Vizinhos) até o Vértice de destino no Grafo.
(defun find-path/list (ns dst g)
NIL)

Agora que find-path está escrita, fica muito mais fácil pensar em
find-path/list porque o que find-path/list faz é usar find-path até
encontrar um caminho, ou seja, find-path/list é trivial: basta percorrer
a lista de Vizinhos um a um. O caso base de find-path/list é quando não
há mais Vizinhos a considerar.

(defun find-path/list (ns end graph)
(cond
((null ns) nil)
(t (let ((subsolution (find-path (car ns) end graph)))
(if subsolution
subsolution
(find-path/list (cdr ns) end graph))))))

CL-USER> (find-path 'A 'G sample-graph)
(A B E F G)
CL-USER> (find-path 'C 'D sample-graph)
(C D)
CL-USER> (find-path 'C 'A sample-graph)
NIL

Solucionado.

(*) Uma expressão mais típica

Usamos /if/ no código acima pra casar com a nossa redação em português,
mas não é a forma idiomática de escrever. Eis uma reescrita.

(defun find-path/list (ns end graph)
(cond
((null ns) nil)
(t (or (find-path (car ns) end graph)
(find-path/list (cdr ns) end graph)))))

(defun find-path (src dst graph)
(cond
((eq src dst) (cons src nil))
(t (and (find-path/list (neighbors src graph) dst graph)
(cons src (find-path/list (neighbors src graph) dst graph))))))

É a solução.

(*) Epílogo

Esse é o processo ensinado pelo HtDP. Mas não é fácil usar isso. Não
diria que realmente compreenda esse processo. Os autores anunciam
também --- especialmente nesses casos de recursão ``generativa'', que é
como eles chama esse tipo, o código muitas vezes exige um certo insight.

Em retrospectiva, posso fazer as seguintes observações. Observe que pra
escrever find-path/list, precisamos de find-path. Pra escrever
find-path, precisamos de find-path/list. Em outras palavras, temos uma
recursão mútua aí. Isso é comum de ocorrer em árvores. Por exemplo,
como se faz pra descer um sistema de arquivos? Dessa forma. Esse grafo
não é nada senão uma árvore. Ele não possui ciclos. Então é preciso
trabalhar de forma mais sistemática --- observando essas coisas. Como
diz Frederick P. Brooks, é preciso prestar atenção à estrutura de dados
primeiro. Os algoritmos em si serão óbvios depois. Essa noção está
explicitamente explorada pelo HtDP.

``Representation Is the Essence of Programming. Much more often,
strategic breakthrough will come from redoing the representation of
the data or tables. This is where the heart of a program lies. Show
me your flowcharts and conceal your tables, and I shall continue to be
mystified. Show me your tables, and I won’t usually need your
flowcharts; they’ll be obvious.'' -- ``The Mythical Man-Month'',
expanded anniversary edition (2nd edition), 1995, Addison-Wesley, ISBN
0-201-83595-9. Página 102.

(*) Novo problema

Encontremos todos os caminhos. Parece moleza. Experimenta.

Daniel Cerqueira

unread,
Jan 19, 2024, 5:39:32 AM1/19/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Eis uma tentativa pela receita HtDP. Um Vértice é um Símbolo. Um
> Vizinhos é uma lista de Símbolos. Um Grafo é um de
>
> - NIL
> - (cons Vértice Vizinhos)
>
> Por exemplo,
>
> NIL ou (list B E))
>
> são Vizinhos. Já A, B, C, ... são Vértices. E, assim,
>
> ((A (B E))
> (B (E F)))
>
> é um grafo. Precisamos de um procedimento neighbors que extrai os
> Vizinhos de um vértice. Como é trivial, usemos /assoc/:
>
> (defun neighbors (v g) (assoc v g))

Esta função "neighbors" está a confundir-me, porque, da maneira com que
está escrita, ela está a devolver a aresta mais o vértice (sendo v um
vértice e g um grafo).

Verifica esta função e vê se está correta.

Será que deveria ficar assim:

(defun neighbors (v g) (cadr (assoc v g)))

?

Patricia Ferreira

unread,
Jan 19, 2024, 6:38:36 AM1/19/24
to
Perdão! Percebi isso depois de escrever o procedimento; atualizei o
código e não postei pra você. Na verdade escrevi

(defun vertex (v graph) (assoc v graph))
(defun neighbors (v graph) (cadr (vertex v graph)))

Sua leitura está correta.

Daniel Cerqueira

unread,
Jan 20, 2024, 8:38:41 AM1/20/24
to
Patricia Ferreira <pfer...@example.com> writes:

> Daniel Cerqueira <dan....@brilhante.top> writes:
>
>> Como resolverias este exercício? :-)
>
> (defun find-path (src dst graph)
> (cond
> ((eq src dst) (cons src nil))
> (t
> (let ((subsolution (find-path/list (neighbors src graph) dst graph)))
> (if subsolution
> (cons src subsolution)
> nil)))))
>
>
> (defun find-path/list (ns end graph)
> (cond
> ((null ns) nil)
> (t (let ((subsolution (find-path (car ns) end graph)))
> (if subsolution
> subsolution
> (find-path/list (cdr ns) end graph))))))
>
> CL-USER> (find-path 'A 'G sample-graph)
> (A B E F G)
> CL-USER> (find-path 'C 'D sample-graph)
> (C D)
> CL-USER> (find-path 'C 'A sample-graph)
> NIL
>
> Solucionado.

Estou (e passei estes últimos dias) a olhar espantado quanto ao
maravilhoso engenho deste algoritmo....

Isto deve ser o que Stallman quer dizer com "playful cleverness" (que é
o significado real da palavra "hacker").

Ainda estou a analisar cuidadosamente os algoritmos. Por serem
regenerativos (acho que é assim o nome), parecem que tem por base ar
puro, isto é, nada em concreto. E funcionam :-) É uma solução
maravilhosa........

> (*) Epílogo
>
> Esse é o processo ensinado pelo HtDP. Mas não é fácil usar isso. Não
> diria que realmente compreenda esse processo. Os autores anunciam
> também --- especialmente nesses casos de recursão ``generativa'', que é
> como eles chama esse tipo, o código muitas vezes exige um certo insight.
>
> Em retrospectiva, posso fazer as seguintes observações. Observe que pra
> escrever find-path/list, precisamos de find-path. Pra escrever
> find-path, precisamos de find-path/list. Em outras palavras, temos uma
> recursão mútua aí. Isso é comum de ocorrer em árvores. Por exemplo,
> como se faz pra descer um sistema de arquivos? Dessa forma. Esse grafo
> não é nada senão uma árvore. Ele não possui ciclos. Então é preciso
> trabalhar de forma mais sistemática --- observando essas coisas. Como
> diz Frederick P. Brooks, é preciso prestar atenção à estrutura de dados
> primeiro. Os algoritmos em si serão óbvios depois. Essa noção está
> explicitamente explorada pelo HtDP.
>
> ``Representation Is the Essence of Programming. Much more often,
> strategic breakthrough will come from redoing the representation of
> the data or tables. This is where the heart of a program lies. Show
> me your flowcharts and conceal your tables, and I shall continue to be
> mystified. Show me your tables, and I won’t usually need your
> flowcharts; they’ll be obvious.'' -- ``The Mythical Man-Month'',
> expanded anniversary edition (2nd edition), 1995, Addison-Wesley, ISBN
> 0-201-83595-9. Página 102.

Ótima citação. Parece que o HtDP tem muito a oferecer.

E esse do "The Mythical Man-Month" já ouvi muitas vezes esse nome, mas
não sei bem de que assunto esse livro trata.

> (*) Novo problema
>
> Encontremos todos os caminhos. Parece moleza. Experimenta.

Vou demorar algum tempo a resolver este último problema. Primeiro quero
entender melhor a solução que des-te.

E vou resolver sim esse novo problema ;-)

Patricia Ferreira

unread,
Jan 20, 2024, 9:42:49 AM1/20/24
to
Somos dois. Mas me parece mais adequado observá-lo nesta forma:

(defun find-path/list (ns end graph)
(cond
((null ns) nil)
(t (or (find-path (car ns) end graph)
(find-path/list (cdr ns) end graph)))))

(defun find-path (src dst graph)
(cond
((eq src dst) (cons src nil))
(t (and (find-path/list (neighbors src graph) dst graph)
(cons src (find-path/list (neighbors src graph) dst graph))))))

> Isto deve ser o que Stallman quer dizer com "playful cleverness" (que é
> o significado real da palavra "hacker").
>
> Ainda estou a analisar cuidadosamente os algoritmos. Por serem
> regenerativos (acho que é assim o nome), parecem que tem por base ar
> puro, isto é, nada em concreto. E funcionam :-) É uma solução
> maravilhosa........

Como traduzimos isso? Não apoio ``regenerativo'', não, porque essa
palavra sugere uma coisa que foi destruída e então recuperou-se. Já
``generativa'' sugere a geração de alguma coisa, que é o que ocorre em
qualquer recursão. Entretanto, a recursão que é obviamente menor que a
anterior é chamada de recursão estrutural ou recursão natural. Essa é a
impressão que tenho. Nunca achei muito fácil definir recursão natural,
estrutura e recursão generativa.

>> (*) Epílogo
>>
>> Esse é o processo ensinado pelo HtDP. Mas não é fácil usar isso. Não
>> diria que realmente compreenda esse processo. Os autores anunciam
>> também --- especialmente nesses casos de recursão ``generativa'', que é
>> como eles chama esse tipo, o código muitas vezes exige um certo insight.
>>
>> Em retrospectiva, posso fazer as seguintes observações. Observe que pra
>> escrever find-path/list, precisamos de find-path. Pra escrever
>> find-path, precisamos de find-path/list. Em outras palavras, temos uma
>> recursão mútua aí. Isso é comum de ocorrer em árvores. Por exemplo,
>> como se faz pra descer um sistema de arquivos? Dessa forma. Esse grafo
>> não é nada senão uma árvore. Ele não possui ciclos. Então é preciso
>> trabalhar de forma mais sistemática --- observando essas coisas. Como
>> diz Frederick P. Brooks, é preciso prestar atenção à estrutura de dados
>> primeiro. Os algoritmos em si serão óbvios depois. Essa noção está
>> explicitamente explorada pelo HtDP.
>>
>> ``Representation Is the Essence of Programming. Much more often,
>> strategic breakthrough will come from redoing the representation of
>> the data or tables. This is where the heart of a program lies. Show
>> me your flowcharts and conceal your tables, and I shall continue to be
>> mystified. Show me your tables, and I won’t usually need your
>> flowcharts; they’ll be obvious.'' -- ``The Mythical Man-Month'',
>> expanded anniversary edition (2nd edition), 1995, Addison-Wesley, ISBN
>> 0-201-83595-9. Página 102.
>
> Ótima citação. Parece que o HtDP tem muito a oferecer.

É. Não é um livro que deveríamos ignorar, já que não enxergamos essas
técnicas com naturalidade. Tem outras coisas que não devemos ignorar,
mas fica pra outro momento.

>> (*) Novo problema
>>
>> Encontremos todos os caminhos. Parece moleza. Experimenta.
>
> Vou demorar algum tempo a resolver este último problema. Primeiro quero
> entender melhor a solução que des-te.
>
> E vou resolver sim esse novo problema ;-)

Tem uma solução que julgo mais ou menos óbvia, mas me pergunto se é uma
solução natural aí no caso. Vou deixar você trabalhar por aí antes de
apresentar. Torço pra que você encontre a solução que eu acho que
deveria existir e não consigo encontrar.

Daniel Cerqueira

unread,
Jan 23, 2024, 12:29:22 PM1/23/24
to
>>> (*) Novo problema
>>>
>>> Encontremos todos os caminhos. Parece moleza. Experimenta.
>>
>> Vou demorar algum tempo a resolver este último problema. Primeiro quero
>> entender melhor a solução que des-te.
>>
>> E vou resolver sim esse novo problema ;-)
>
> Tem uma solução que julgo mais ou menos óbvia, mas me pergunto se é uma
> solução natural aí no caso. Vou deixar você trabalhar por aí antes de
> apresentar. Torço pra que você encontre a solução que eu acho que
> deveria existir e não consigo encontrar.

Bem, acho que encontrei a solução adquada. Alguns dos meus algoritmos
fazem duas vezes a mesma operação, por isso só falta optimiza-los para
nestas vezes, guardar o valor numa variável.

Aqui vai a minha resposta:

(defun cdrs (lists)
(mapcar #'cdr lists))

(defun cars (lists)
(mapcar #'car lists))

(defun diff (path-a path-b)
(cond
((null (member (car path-a) path-b)) path-a)
(t (diff (cdr path-a) path-b))))

(defun neighbors-exclude (exclude-lists list)
(diff list (cars exclude-lists)))

(defun find-path2 (src dst exclude-lists graph)
(cond
((eq src dst) (cons dst nil))
((null
(find-path/list2
(neighbors-exclude (cdrs exclude-lists) (neighbors src graph))
dst (cdrs exclude-lists) graph))
nil)
(t (cons
src
(find-path/list2
(neighbors-exclude (cdrs exclude-lists) (neighbors src graph))
dst (cdrs exclude-lists) graph)))))

(defun find-path/list2 (ns end exclude-lists graph)
(cond
((null ns) nil)
((null (find-path2 (car ns) end exclude-lists graph))
(find-path/list2 (cdr ns) end exclude-lists graph))
(t (find-path2 (car ns) end exclude-lists graph))))

(defun paths (src dst graph &optional exclude-lists)
(cond
((null (find-path2 src dst exclude-lists graph)) nil)
(t (cons
(find-path2 src dst exclude-lists graph)
(paths src dst graph
(push (find-path2 src dst exclude-lists graph) exclude-lists))))))


A função a ser executada é a função ``paths''. Consegues verificar-me se
funciona corretamente?

Daniel Cerqueira

unread,
Feb 3, 2024, 6:19:54 AM2/3/24
to
Patrícia, qual é a tua solução a este problema? Ainda falta-te dizer.

Patricia Ferreira

unread,
Feb 3, 2024, 7:29:02 AM2/3/24
to
Daniel Cerqueira <dan....@brilhante.top> writes:

[...]

Opa! Parece que deixei passar seu artigo de 23 de janeiro---perdão. Só
com essa nova mensagem percebi. Ainda bem que postou. Deixe-me estudar
sua solução acima.

Sabe qual é a minha solução? A minha é---use find-path pra encontrar um
primeiro caminho de SRC a DST. Se houver caminho, é porque SRC tem
algum vizinho que de fato nos leva a DST. Remova esse vizinho gráfico e
tente de novo---repita até que não haja mais caminho. Estou vendo seu
exclude-lists acima---talvez você tenha feito o mesmo.

Pra remover um vizinho de SRC, eu uso neighbor-, que consome um grafo e
um vértice e produz um grafo sem o primeiro /vizinho/ de SRC. (Torço
pra que o código abaixo esteja completo).

A propósito, estávamos escrevendo Lisp ou Scheme? Parece que mudei pra
Scheme? Já nem lembro o que estávamos fazendo. :-)

(define (find-path src dst graph)
(cond
([symbol=? src dst] (list src))
[else (let ((candidate (find-path/list (neighbors src graph) dst graph)))
(and candidate
(cons src candidate)))]))

(define (find-path/list ns end graph)
(cond
[(null? ns) #f]
[else (or (find-path (car ns) end graph)
(find-path/list (cdr ns) end graph))]))

(define (find-all-paths src dst graph [acc '()])
(let ((path (find-path src dst graph)))
(if path
(find-all-paths src dst (neighbor- src graph) (cons path acc))
acc)))

(define (neighbor- s graph)
;; Symbol Graph --> Graph
;; interp. Removes a neighbor from Node represented by Symbol s
(let* ((ns (neighbors s graph)) ;; [n]eighbor[s]
(nn (list s (cdr ns)))) ;; [n]ew [n]ode
(cons nn (graph- s graph))))

(define (graph- s graph)
(filter (λ (n) (symbol=? (node-name n) s)) graph))

(define (node v graph) (assoc v graph))
(define (node-name v) (car v))
(define (neighbors v graph) (cdr (node v graph)))

Daniel Cerqueira

unread,
Feb 3, 2024, 8:15:00 AM2/3/24
to
Estamos a escrever em Common Lisp! :-) Mudaste para Scheme, acho eu.

Patricia Ferreira

unread,
Feb 3, 2024, 12:52:26 PM2/3/24
to
Por que push aqui quando você já está usando cons quando quer construir
uma lista? Será que você tá usando exclude-lists de forma global? Não
faz sentido, já que você passando ela como argumento pra /paths/.

> A função a ser executada é a função ``paths''. Consegues verificar-me se
> funciona corretamente?

Aparentemente sim, mas você parece entrar num laço infinito com

(paths 'a 'a sample-graph).

Como funciona? Não é óbvia a estratégia.

Parece que find-path2 seria a solução pra um qualquer caminho---seria a
solução anterior. Mas, não---você teve que alterá-la substancialmente
pra poder obter a nova. Tenho dificuldade de entendê-la. Não só
estamos preocupados com exclude-lists, mas também em excluir vizinhos.

Essa exclude-lists talvez fosse melhor chamada de exclude-paths.

A solução que julguei ``mais ou menos óbvia'' foi a que sugeri em
mensagem anterior hoje---computa-se um caminho a partir do primeiro
vizinho; remove-se o vizinho do grafo e computa-se de novo. Repita até
não haver mais caminho---sinal de que não há mais vizinhos que nos leve
ao destino.

Daniel Cerqueira

unread,
Feb 3, 2024, 1:09:32 PM2/3/24
to
exclude-paths parece-me um bom nome.

O push é porque a variável exclude-lists é do tipo lista de listas, e
faço um push de um path, para assim saber que esse path já foi obtido (e
tentar outro).

Ainda preciso de arranjar a minha solução, mas é uma maneira mais
eficiente que calcular todos os paths com remoção de vizinhos.

Não é óbvio de entender a minha solução; por isso também irei tentar
fazer com que seja mais fácil a sua leitura.

Patricia Ferreira

unread,
Feb 3, 2024, 6:48:36 PM2/3/24
to
Combinado. Então vou esperar. E a minha ``mais ou menos óbvia''? Deu
pra entender? Eu teria pensado que haveria uma solução mais fácil de
fazer, dado que conseguimos escrever find-path. Mas você viu o trabalho
que nós dois tivemos em ambos os casos? Por isso eu disse---parece
moleza. Só faltou dizer---mas não é (pra mim, pelo menos). Mas não
queria te influenciar. O fato é---o problema não é trivial (pra mim).
O que está me faltando?

Daniel Cerqueira

unread,
Feb 4, 2024, 6:42:51 AM2/4/24
to
Sim, não é moleza. Ainda não vi a fundo a tua solução, porque ainda
estou a tentar fazer a minha solução.

O que está faltando? Não sei. Mas só há duas soluções: ou se vai
removendo elementos do sample-graph (a tua solução), ou se cria e usa
uma lista de paths a serem evitados quando se está a calcular um
caminho, para se poder encontrar outros paths diferentes (a minha
solução).

Eu não queria fazer isto, mas vou ter de fazê-lo. Tenho de alterar o
código para que não consuma o sample-graph, evitando usar o cdr e
passando a usar o nth+um-integer-de-posição. Assim dá para percorrer o
grafo, mantendo este sempre no estado inicial, para assim poder comparar
o caminho que se está a obter, com os caminhos já obtidos da lista de
exclusão. É necessário o nth porque tenho de comparar o caminho desde o
ínicio, não um cdr (ou cddr, cdddr, etc.) desse caminho.

Isto é necessário na minha solução.

Daniel Cerqueira

unread,
Feb 5, 2024, 10:43:17 AM2/5/24
to
Patricia Ferreira <pfer...@example.com> writes:

>
> [...]
>
>>>>>> (*) Novo problema
>>>>>>
>>>>>> Encontremos todos os caminhos. Parece moleza. Experimenta.

Descobri a solução. Em Common Lisp (não em Scheme) :-P

Vai aqui o código completo. As funções "no", "vizinhos", "caminho" e
"caminho/lista", são as que tinhamos descoberto anteriormente.

Esta solução (tal como a tua), vai removendo elementos de GRAPH para
encontrar caminhos alternativos. O truque desta solução é que ao
remover, remove de GRAPH um elemento igual ao penúltimo elemento de um
dado caminho LIST. Assim mantem-se o DST de um caminho em GRAPH.

Se, após a remoção, o caminho alternativo der NIL, não existe mais
caminhos possíveis no GRAPH, desde SRC até DST.

Este código está completo. Podes copiar, colar, avaliar/compilar, e
correr. A função que descobre todos os caminho é "caminhos".


(defparameter graph
'((A (B E))
(B (E F))
(C (D))
(D ())
(E (C F))
(F (D G))
(G ())))

(defun no (node graph)
"Retorna um nó NODE de um grafo GRAPH."
(assoc node graph))

(defun vizinhos (node graph)
"Retorna os vizinhos de NODE de um grafo GRAPH."
(cadr (no node graph)))

(defun caminho (src dst graph)
"Retorna um caminho desde SRC até DST de um GRAPH."
(cond
((eq src dst) (cons dst nil))
(t
(let ((caminho-de-lista-de-vizinhos (caminho/lista (vizinhos src graph) dst graph)))
(cond
((null caminho-de-lista-de-vizinhos) nil) ; se chegou a um beco sem saída, isto é, um vizinho nil, retorna nil
(t (cons src caminho-de-lista-de-vizinhos)))))))

(defun caminho/lista (list dst graph)
"Retorna um caminho desde uma lista LIST até DST de um GRAPH. Retorna NIL caso não haja qualquer caminho."
(cond
((null list) nil) ; fim da list
(t
(let ((caminho-de-atomo (caminho (car list) dst graph)))
(cond
((consp caminho-de-atomo) caminho-de-atomo) ; caminho de o primeiro vizinho (depende de função anterior)
(t (caminho/lista (cdr list) dst graph))))))) ; ver restante da list

(defun remover-penultimo (list graph)
"Remove de GRAPH um nó igual ao penultimo átomo de LIST."
(remove-if #'(lambda (el) (eq (nth (- (length list) 2) list) (car el))) graph))

(defun cortar-grafo (graph previous-paths)
"Corta no grafo GRAPH o(s) nó(s) igual(ais) ao penultimo átomo de cada caminho de PREVIOUS-PATHS."
(cond
((null previous-paths) graph)
(t (cortar-grafo
(remover-penultimo (car previous-paths) graph)
(cdr previous-paths)))))

(defun caminhos-alternativos (src dst graph previous-paths)
"Retorna um caminho desde SRC até DST de um GRAPH, que seja diferente dos caminhos de PREVIOUS-PATHS."
(let ((novo-caminho (caminho src dst (cortar-grafo graph previous-paths))))
(cond
((null novo-caminho) previous-paths)
(t (caminhos-alternativos src dst graph (push novo-caminho previous-paths))))))

(defun caminhos (src dst graph)
"Retorna todos os caminhos desde SRC até DST de um GRAPH. Retorna NIL caso não haja caminho."
(let ((um-caminho (caminho src dst graph)))
(cond
((null um-caminho) nil)
((eq src dst) (list (list src)))
(t (caminhos-alternativos src dst graph (list um-caminho))))))

Patricia Ferreira

unread,
Feb 5, 2024, 4:50:43 PM2/5/24
to
Não compreendo a necessidade de /push/ aqui.

> (defun caminhos (src dst graph)
> "Retorna todos os caminhos desde SRC até DST de um GRAPH. Retorna NIL caso não haja caminho."
> (let ((um-caminho (caminho src dst graph)))
> (cond
> ((null um-caminho) nil)
> ((eq src dst) (list (list src)))
> (t (caminhos-alternativos src dst graph (list um-caminho))))))

A expressão está bem melhor. É engraçado como código tem uma certa
forma. Um especialista em xadrez olha pra um tabuleiro e rapidamente
nota se alguma coisa não faz sentido.

Daniel Cerqueira

unread,
Feb 6, 2024, 5:55:39 AM2/6/24
to
Por o argumento de caminhos-alternativos ser uma lista de lista, o push
é uma maneira de adicionar uma lista a esta lista de listas.

>> (defun caminhos (src dst graph)
>> "Retorna todos os caminhos desde SRC até DST de um GRAPH. Retorna NIL caso não haja caminho."
>> (let ((um-caminho (caminho src dst graph)))
>> (cond
>> ((null um-caminho) nil)
>> ((eq src dst) (list (list src)))
>> (t (caminhos-alternativos src dst graph (list um-caminho))))))
>
> A expressão está bem melhor. É engraçado como código tem uma certa
> forma. Um especialista em xadrez olha pra um tabuleiro e rapidamente
> nota se alguma coisa não faz sentido.

Tenho más notícias.... esta solução continua a não retornar todos os
caminhos. Por exemplo: (caminhos 'b 'd graph) retorna apenas 2 caminhos,
quando deveria retornar 3 caminhos.

Após ter enviado este artigo, comecei a trabalhar numa solução que
solucionasse isto de maneira definitiva. Já tenho a solução, que vou
postar num artigo próprio.

Daniel Cerqueira

unread,
Feb 6, 2024, 6:11:12 AM2/6/24
to
Patricia Ferreira <pfer...@example.com> writes:

[...]

>>>>>> (*) Novo problema
>>>>>>
>>>>>> Encontremos todos os caminhos. Parece moleza. Experimenta.

Aqui está a minha solução a este problema. Com uma nova abordagem.

Esta solução é mais intensa na memória, mas estou a falhar em encontrar
uma solução mais suave para a memória do computador.

Aqui as funções "no", "vizinhos", "caminho" e "caminho/lista" são as
funções que já descobrimos nos exercícios anteriores.

A técnica aqui reside em criar uma lista de grafos, em que tem todos os
grafos na qual falta apenas um nó dos nós iniciais. Esta é a parte
intensiva para a memória.

Depois calculo todos os caminhos usando este /multiverso de grafos/ e
vou armazenando os caminhos únicos numa váriavel (local). Para depois
retornar esta variável.

Aqui a função que retorna todos os caminhos é "caminhos".

Patrícia, se descobrires outra abordagem que retorne todos os caminhos,
quero ouvir sobre ela. Uma maneira simples de testar, se retorna todos
os caminhos, é calcular os caminhos desde B até D, tendo de retornar 3
caminhos ;-)


(defparameter graph
'((A (B E))
(B (E F))
(C (D))
(D ())
(E (C F))
(F (D G))
(G ())))

(defun no (node graph)
"Retorna um nó NODE de um grafo GRAPH."
(assoc node graph))

(defun vizinhos (node graph)
"Retorna os vizinhos de NODE de um grafo GRAPH."
(cadr (no node graph)))

(defun caminho (src dst graph)
"Retorna um caminho desde SRC até DST de um GRAPH."
(cond
((eq src dst) (cons dst nil))
(t
(let* ((lista-de-vizinhos (vizinhos src graph))
(caminho-de-lista-de-vizinhos (caminho/lista lista-de-vizinhos dst graph)))
(cond
((null caminho-de-lista-de-vizinhos) nil) ; se chegou a um beco sem saída, isto é, um vizinho nil, retorna nil
(t (cons src caminho-de-lista-de-vizinhos)))))))

(defun caminho/lista (list dst graph)
"Retorna um caminho desde uma lista LIST até DST de um GRAPH. Retorna NIL caso não haja qualquer caminho."
(cond
((null list) nil) ; fim da list
(t
(let ((caminho-de-atomo (caminho (car list) dst graph)))
(cond
((consp caminho-de-atomo) caminho-de-atomo) ; caminho de o primeiro vizinho (depende de função anterior)
(t (caminho/lista (cdr list) dst graph))))))) ; ver restante da list

(defun remover-no (number graph)
"Remove um nó de GRAPH por posição NUMBER (primeira posição é o zero)"
(remove-if #'(lambda (el) (eq el (nth number graph))) graph))

(defun grafo-multiverso (graph &optional number)
"Retorna uma lista com todas as variações de GRAPH em que falta, em cada grafo, um nó."
(cond
((null number) (cons graph (grafo-multiverso graph 0)))
((eq number (length graph)) nil)
(t (cons (remover-no number graph) (grafo-multiverso graph (1+ number))))))

(defun caminho-map (src dst graph-multiverse result)
"Retorna todos os caminhos (RESULT) únicos desde SRC até DST, da lista de grafos GRAPH-MULTIVERSE. Retorna RESULT caso não haja qualquer caminho."
(let ((caminho (caminho src dst (car graph-multiverse))))
(cond
((null graph-multiverse) result)
((or
(null caminho)
(consp (member caminho result :test #'equal)))
(caminho-map src dst (cdr graph-multiverse) result))
(t (caminho-map src dst (cdr graph-multiverse) (push caminho result))))))

(defun caminhos (src dst graph)
"Retorna todos os caminhos de GRAPH, desde SRC até DST. Retorna NIL se não há qualquer caminho."
(caminho-map src dst (grafo-multiverso graph) nil))

Patricia Ferreira

unread,
Feb 6, 2024, 4:13:16 PM2/6/24
to
Você não pode usar cons pra isso?

>>> (defun caminhos (src dst graph)
>>> "Retorna todos os caminhos desde SRC até DST de um GRAPH. Retorna NIL caso não haja caminho."
>>> (let ((um-caminho (caminho src dst graph)))
>>> (cond
>>> ((null um-caminho) nil)
>>> ((eq src dst) (list (list src)))
>>> (t (caminhos-alternativos src dst graph (list um-caminho))))))
>>
>> A expressão está bem melhor. É engraçado como código tem uma certa
>> forma. Um especialista em xadrez olha pra um tabuleiro e rapidamente
>> nota se alguma coisa não faz sentido.
>
> Tenho más notícias.... esta solução continua a não retornar todos os
> caminhos. Por exemplo: (caminhos 'b 'd graph) retorna apenas 2 caminhos,
> quando deveria retornar 3 caminhos.
>
> Após ter enviado este artigo, comecei a trabalhar numa solução que
> solucionasse isto de maneira definitiva. Já tenho a solução, que vou
> postar num artigo próprio.

Okay!
0 new messages