✍ diale.org

Webpage of Tiago Charters de Azevedo

Início/Start Arquivo/Archive AdNauseum Notas/Notes Contact me RSS


All work and no play...

with Arduino and TVout

2016/07/23-00:01:49

So I've been playing with Arduino and the TVout library... fun, fun, fun!

#include <TVout.h>
#include <TVoutfonts/fontALL.h>
#include "TVOlogo.h"

TVout TV;

void setup(){
  TV.begin(_PAL); // for PAL system
  TV.clear_screen();
}

void loop(){
  TV.select_font(font4x6);
  
  TV.set_cursor(0,0);
  TV.print("All work");

  TV.set_cursor(0,7);
  TV.print("and no play");
  
  TV.set_cursor(0,14);
  TV.print("makes Jack a dull boy...");

  TV.bitmap(0,21,TVOlogo);
}

Refs.:

Happy hacking!

Etiquetas/Tags: Arduino, TVout

Doing a drawbot...

using servos and arduino

2016/06/30-12:53:08

First the results... it really does not work.

Lots of vibrations and errors... but a lot of fun.

Here's the GNU/Octave code to generate the .ino file.

Happy hacking!

clear all

l1=18.5;
l2=20;
d=-15;
n=200;
t=linspace(0,20*pi,n);
x=d+5*cos(t).*exp(-.05*t);
y=5*sin(t).*exp(-.05*t);
alpha(1)=   -4.5980
beta(1)=   4.3070

for i=1:n-1
  aux= newtonsys([alpha(i) beta(i)],[x(i+1) y(i+1)],1e-3,l1,l2);
  
  alpha(i+1)=aux(1);
  beta(i+1)=aux(2);
end


theta1=-alpha*180/pi-180;
theta2=beta*180/pi-180;


## Write to INO
filename="~/Arduino/examples/servo/servo.ino"

comment_str="This is a comment on the begining of the .ino file ;)";
fid=fopen(filename,'w');
fprintf(fid,'/* %s */\n',comment_str);

header_str="\n#include <Servo.h>\n\nServo Servo1;\nServo Servo2;\n\n";
preamble_str="\nvoid setup()\{\n    Servo2.attach(10);\n    Servo1.attach(9);\}\n\nvoid loop(){\n";

fprintf(fid,'%s',header_str);
fprintf(fid,'%s',preamble_str);

for i=1:n
  fprintf(fid,'%s%f%s',"Servo1.write(",theta1(i),");\n");
  fprintf(fid,'%s%f%s',"Servo2.write(",theta2(i),");\n");
  fprintf(fid,'%s',"delay(100);\n");


end
fprintf(fid,'%s',"}");
fclose(fid);

############################################################
figure(1)
clf
hold on
plot(x,y)
u=l1*cos(alpha)+l2*cos(beta);
v=l1*sin(alpha)+l2*sin(beta);
plot(u,v,'r-')

############################################################
figure(2)
clf
hold on
plot(l1*cos(theta1)+l2*cos(theta2),l1*sin(theta2)+l2*cos(theta2),'-')
plot(l2*cos(beta),l2*sin(beta),'r-')
plot(l1*cos(alpha(1)),l1*sin(alpha(1)),'o')

[t' alpha' beta' theta1' theta2']

function Fv=Ffun(x,xpos,l1,l2)
  Fv(1,1)=xpos(1)-l1*cos(x(1))-l2*cos(x(2));
  Fv(2,1)=xpos(2)-l1*sin(x(1))-l2*sin(x(2));
end
function Jv=Jfun(x,l1,l2)
  Jv(1,1)=l1*sin(x(1));
  Jv(1,2)=l2*sin(x(2));
  Jv(2,1)=-l1*cos(x(1));
  Jv(2,2)=-l2*cos(x(2));
end
function x=newtonsys(xo,xpos,tol,l1,l2)
  Niter=1000;
  x=xo';
  delta=eye(length(xo),1);

  i=0;
  while or(i<=Niter, abs(max(delta))>tol)
      Jv=Jfun(x,l1,l2);
      Fv=Ffun(x,xpos,l1,l2);
      delta=-Jv\Fv;
      x=x+delta;
      i=i+1;
  endwhile
end

Etiquetas/Tags: arduino, draw bot, Octave, ino

"Now, a tricolumn - build this efficiente column speaker" by R. N.Baldock.

... simple idea for using a CNC.

2016/06/16-14:55:56

Here is a simple idea for building a tricolumn with a F88 Fountek speaker.

And the final construction:

Etiquetas/Tags: CNC, tricolumn, speaker, audio

Prusa i3 pro B

... a wood frame version

2016/06/16-10:12:21

So instead of this fragile wood frame

this

It's a hybrid version, between a Prusa i3 Pro B and a Mendel 90. Works nicely!

P.S.

In you are wandering it as a GT2560 board:

[#define MOTHERBOARD BOARD_ULTIMAKER]

board nr. 7. 

Etiquetas/Tags: diy, 3d printer, prusa i3 pro b

Speaker enclosure resistance vent

3D printed

2016/06/15-17:02:27

This a simple hack of a resistor vent (https://www.youmagine.com/tca/).The basic idea is to build a small speaker enclosure and use a resistance vent to minimize the boomimg effect that the small box imposes on the final frequency response.

More details here: http://diyaudioprojects.com/Technical/Aperiodic/

Typically these resistors have 10cm diameter. The default STL's are for a 8cm hole, but you can tailor it using the SCAD file attached (see end of page).

Happy hacking!

Notes:

Printer Brand: RepRap

Printer: Prusa i3

Rafts: No

Supports: No

Resolution: .2mm

Infill: 20%

Here's de OpenSCAD code

// Author: Tiago Charters de Azevedo 
// Maintainer: Tiago Charters de Azevedo 

// Copyright (c) - 2016 Tiago Charters de Azevedo (tca@diale.org)

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor,
// Boston, MA 02110-1301, USA.

$fn=64;
h=7.5;
R=40;
eps=.2;
n=4;
thickness=2;
screw=3;

module top(){
    translate([0,0,thickness/2]){
        difference(){
            difference(){
                cylinder(thickness,R+3*screw,R+3*screw,center=true);
                cylinder(2*thickness,R-eps-thickness,R-eps-thickness,center=true);}
                for(i=[0:2]){
                    rotate([0,0,i*360/3]){
                        translate([0,R+2*screw/3,0]){
                            cylinder(10,screw/2+eps,screw/2+eps,center=true);}}}}}
    
    
 translate([0,0,(h+thickness)/2]){
        difference(){
            cylinder(h+thickness,R-eps-thickness,R-eps-thickness,center=true);
            cylinder(10*h,R-eps-2*thickness,R-eps-2*thickness,center=true);}}
    
    intersection(){
        union(){
            for(i=[-n:n]){
                translate([i*R/n,0,1]){
                    cube([2,2*R,2],center=true);}}
            
            rotate([0,0,90]){
                for(i=[-n:n]){
                    translate([i*R/n,0,1]){
                        cube([2,2*R,2],center=true);}}}}
        
        cylinder(50,R-eps-thickness,R-eps-thickness,center=true);}}

////////////////////////////////////////////////////////////

module bottom(){
    rotate([0,0,0]){
        translate([0,0,0]){
            translate([0,0,h/2]){
                difference(){
                    cylinder(h+thickness,R,R,center=true);
                    cylinder(5*h,R-thickness,R-thickness,center=true);}}
            
            intersection(){
                union(){
                    for(i=[-n:n]){
                        translate([i*(R)/n,0,0]){
                            cube([2,2*(R-eps),2],center=true);}}
                    
                    rotate([0,0,90]){
                        for(i=[-n:n]){
                            translate([i*(R)/n,0,0]){
                                cube([2,2*(R-eps),2],center=true);}}}}
                cylinder(50,R-eps,R-eps,center=true);}}}}



//!top();
//!bottom();

!alltosee();

module alltosee(){
    top();
    rotate([0,180,0]){
        translate([0,0,-4*h,]){
            bottom();
        }}}

Added some handles and feet;)

Etiquetas/Tags: audio, speaker enclosure, vent, variovent

3D printer

... from far east

2016/05/26-22:36:06

I recently bought a kit from China of a Prusa i3 Pro B

The software did not have a interactive way for leveling the bed... so here's the gcode for it! ;) Just levels the bed and starts heating... getting ready for printing.

;G0 rapid linear move
;G1 linear move

M104 S0                     ;extruder heater off
M140 S0  

G21        ;metric values
G90        ;absolute positioning
M82        ;set extruder to absolute mode
M107       ;start with the fan off
G28 X0 Y0  ;move X/Y to min endstops
G28 Z0     ;move Z to min endstops


;Put printing message on LCD screen
M117 Leveling bed...
M0

G1 X0 Y0 Z1
G1 X20 Y20 Z1
G1 X20 Y20 Z0
M117 Press button when finish...
M0
G1 X20 Y20 Z1

G1 X20 Y180 Z1
G1 X20 Y180 Z0
M117 Press button when finish...
M0
G1 X20 Y180 Z1


G1 X180 Y180 Z1
G1 X180 Y180 Z0
M117 Press button when finish...
M0
G1 X180 Y180 Z1

G1 X180 Y20 Z1
G1 X180 Y20 Z0
M117 Press button when finish...
M0
G1 X180 Y20 Z1

G1 X90 Y90 Z1
G1 X90 Y90 Z0
M117 Done!
M0

G1 X90 Y90 Z1

G28 X0 Y0  ;move X/Y to min endstops
G28 Z0     ;move Z to min endstops


M84                         ;steppers off
G90                         ;absolute positioning

M117 Prepare for printing...
M190 S70  ;set bed temperature                         
M109 S215 ;set nozzle temperature                         

Happy hacking!

P.S.

One more

; Simple gcode start up script for my far east printer (prusa i3 pro b)
M104 S0    ;extruder heater off
M140 S0  

G21        ;metric values
G90        ;absolute positioning
M82        ;set extruder to absolute mode
M107       ;start with the fan off
G28 X0 Y0 Z0  ;move X/Y/Z to min endstops
G1 X0 Y0 Z10  ;move 10mm up

M109 S215 ;Wait for nozzle temperature to reach target temp
G1 X0 Y0 Z50 ;move 40mm up
G1 X0 Y0 Z20 E30 ;extrudes 30mm of filament

M190 S70  ;Wait for bed temperature to reach target temp

M117 Ready for printing.

Etiquetas/Tags: 3d, printer, china, pla, abs, gcode

Ping-Pong Anemometer

3D printed...

2016/05/10-09:16:16

Sphere anemometers are simple devices that use the wind drag force on a sphere to determine the wind speed by equating the weight of the sphere with the drag force in a pendulum like configuration.

The drag force is the force that a sphere feels when traveling with a certain speed latex2png equation in a viscous fluid (relatively to the fluid, in our case air). This forces depends on the relative velocity between the air and the sphere, on the density of the air latex2png equation, effective area in contact with the fluidlatex2png equation and an adimensional coefficient latex2png equation called the drag coefficient. In this case this force amounts to

latex2png equation

Note that the drag coefficient latex2png equation is a geometric factor and is usually determined experimentally. For a sphere, for high enough Reynolds numbers, the drag coefficient is around 0.5.

Apparently this kind of anemometer was invented in 1900 by G. Daloz. Modern versions includes a ping-pong ball.

Equating the weight of the sphere

latex2png equation

with the drag force in a pendulum like configuration for a given equilibrium position one gets

latex2png equation

and for the velocity:

latex2png equation Where D=2 R is the diameter of the ping-pong ball.

Given that a ping-pong ball has mass of 2.7g and a typical diameter of 40mm one gets for the density rhoball=2.7/(4*pi/3*2^3)~0.081 g/cm^3

and thus

latex2png equation

Here's the OpenSCAD file:

// Author: Tiago Charters de Azevedo
// Maintainer: Tiago Charters de Azevedo 

// Copyright (c) - 2016 Tiago Charters de Azevedo (tca@diale.org)

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor,
// Boston, MA 02110-1301, USA.


// Gravity aceleration
g=9.8; //(m/s^2)
rhoair=0.001225; // (g/cm^3)
// pi
pi=3.1415926;

/*Drag coeficiente
.5 sphere
see: https://en.wikipedia.org/wiki/Drag_coefficient
*/
Cd=.47;

// Ping-Pong
D=.04; // (m)
mball=2.7; // (g)
A=pi*pow(D/2,2);
rhoball=mball/(4*pi/3*pow(100*D/2,3));// 0.081; // (g/cm^3)

// Font size
fsize=4;

R=100;
h=2;

coef=1;//3.6*0.621371;
module slice(h=2){
    difference(){
        cylinder(h,R,R,center=true,$fn=64);
        translate([0,2.5*R/2,0]){
            cube([2.5*R,2.5*R,2*h],center=true);}
        translate([2.5*R/2,0,0]){
            cube([2.5*R,2.5*R,2*h],center=true);}}}

module vscale(){
    for(alpha=[0:5:89]){
        v=coef*sqrt(pi*g*rhoball*pow(D,3)*tan(alpha)/(3*A*Cd*rhoair));
        rotate([0,0,alpha]){
            translate([-R*.99,0,-0]){
                rotate([0,0,-0]){
                    linear_extrude(height=h,scale=1,twist=0,convexity= 0){          
                        text(str(floor(v*10)/10),size=fsize,font="Arial Black:style=Bold",center=true);}}}
            
            translate([-R*.8,-1*0,h/2]){
                sphere(h/2,center=true,$fn=64);}}}
    
    translate([-R*.7,-1*0,h/2]){
        sphere(h/2,center=true,$fn=64);}
    
    
    translate([0,-R+2,0]){
        rotate([0,0,90]){
            linear_extrude(height=h,scale=1,twist=0,convexity= 0){          
                text("m/s",size=fsize,font="Arial Black:style=Bold",center=true);}}}}

//difference()
{
    intersection(){
        union(){
            difference(){
                slice();
                cylinder(10,R*.7,R*.7,center=true,$fn=64);}
            translate([0,-R/2,0]){
                cube([6*h,R,h],center=true);}
            translate([-R/2,0,0]){
                cube([R,6*h,h],center=true);}}
        cylinder(10*h,R,R,center=true,$fn=64);}
    vscale();}


cylinder(h,3*h,3*h,center=true,$fn=64);

difference(){
    union(){
        cylinder(3*h,h,h,center=false,$fn=64);
        translate([0,0,3*h]){
    sphere(h,center=true,$fn=64);}}
    translate([0,0,2.5*h]){
        rotate([0,90,0]){
            cylinder(3*h,1,1,center=true,$fn=64);}}}

Etiquetas/Tags: anemometer, ping-pong, 3d printer

0's e 1's Stern-Brocot

... outra implementação

2016/01/27-19:45:06

Depois da a implementação da árvore de Stern-Brocot em LISP, uma conversa com um colega revelou outra forma de a construir. A saber, usar símbolos. A sugestão incluía usar L e R e uma ordenação lexicográfica: L<R, mas 0's e 1's servem perfeitamente para o efeito. Construir qualquer coisa do género

0: (0,1)
1: (0,01,1)
2: (0,010,01,011,1)
...
onde o nível (k+1) obtém-se intercalando, entre cada duas sequências de (k), a concatenação das mesmas, começando pela maior com 0 inicial.

A ideia é a mesma da implementação anterior. Começa-se pela construção do mediante

(defun mediant (lst1 lst2)
  (cond ((and (= 0 (car lst2))
              (> (length lst2) (length lst1)))
         (append lst2 lst1))
        (t
         (append lst1 lst2))))

;; Example
> (mediant '(0) '(1))
(0 1)
Depois,
(defun mediant-list (01-lst)
  (cond ((cadr 01-lst)
         (append (list (car 01-lst)
                       (mediant (car 01-lst) (cadr 01-lst)))
                 (mediant-list (cdr 01-lst))))
        (t
         01-lst)))

;; Example
> (mediant-list '((0) (1)))
((0) (0 1) (1))
> (mediant-list '((0) (0 1) (1)))
((0) (0 1 0) (0 1) (0 1 1) (1))
ou mais completamente
> (mediant-list
 (mediant-list
  (mediant-list '((0) (1)))))
((0) (0 1 0 0) (0 1 0) (0 1 0 0 1) (0 1) (0 1 1 0 1) (0 1 1) (0 1 1 1) (1))

E finalmente

(defun stern-brocot (01-list n)
  (nest #'mediant-list 01-list n))

;; Example
> (stern-brocot '((0) (1)) 5)
((0) (0 1 0 0 0 0) (0 1 0 0 0) (0 1 0 0 0 0 1 0 0) (0 1 0 0)
 (0 1 0 0 0 1 0 0 1 0 0) (0 1 0 0 0 1 0) (0 1 0 0 0 1 0 0 1 0) (0 1 0)
 (0 1 0 0 1 0 1 0 0 1 0) (0 1 0 0 1 0 1 0) (0 1 0 0 1 0 1 0 0 1 0 0 1)
 (0 1 0 0 1) (0 1 0 0 1 0 1 0 1 0 0 1) (0 1 0 0 1 0 1) (0 1 0 0 1 0 1 0 1)
 (0 1) (0 1 1 0 1 0 1 0 1) (0 1 1 0 1 0 1) (0 1 1 0 1 0 1 0 1 1 0 1)
 (0 1 1 0 1) (0 1 1 0 1 0 1 1 0 1 1 0 1) (0 1 1 0 1 0 1 1)
 (0 1 1 0 1 0 1 1 0 1 1) (0 1 1) (0 1 1 1 0 1 1 0 1 1) (0 1 1 1 0 1 1)
 (0 1 1 1 0 1 1 0 1 1 1) (0 1 1 1) (0 1 1 1 1 0 1 1 1) (0 1 1 1 1)
 (0 1 1 1 1 1) (1))
usando para a composição
(defun nest (function arg n)
  (cond ((= n 0)
         arg)
        (t 
         (nest function (funcall function arg) (- n 1)))))

Claro que posso sempre voltar aos racionais ;)

(defun back-to-rationals (01-lst)
  (mapcar (lambda (x)(/ (sum x)
                        (length x))) 01-lst))

;; Example
(back-to-rationals (stern-brocot '((0) (1)) 5))
(0 1/6 1/5 2/9 1/4 3/11 2/7 3/10 1/3 4/11 3/8 5/13 2/5 5/12 3/7 4/9 1/2 5/9 4/7
 7/12 3/5 8/13 5/8 7/11 2/3 7/10 5/7 8/11 3/4 7/9 4/5 5/6 1)
usando a função auxiliar
(defun sum (lst)
  (cond (lst
         (+ (car lst)
            (sum (cdr lst))))
        (t
         0)))

;; ore using reduce

(defun sum(lst)
  (reduce #'+ lst))

Etiquetas/Tags: Stern-Brocot, LISP, hack

Implementação do LISP de John McCarthy, de 1960

Implementação do LISP de JMC de 1960 em LTK

2016/01/25-15:38:28

Hoje tive tempo para acabar a implementação do LISP de 1960 de John McCarthy (Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I, Communications of the ACM 3:4, April 1960, pp. 184-195) em LTK. O código está aqui.

A imagem mostra uma das funções descrita no artigo.

(provide :1960-lisp)
(load "/home/tca/lisp_packages/ltk/ltk.lisp")
(defpackage :1960-lisp
  (:use :common-lisp :ltk)
  (:export lisp)
  (:documentation "1960-lisp is a CL implementation of John McCarthy's  LISP from the paper
    Recursive Functions of Symbolic Expressions and Their Computation by Machine, higly inspired in Paul Graham's
    The Roots of Lisp"))

(in-package :1960-lisp)

(setf tutorial "Examples: 

 1. ((eq 'a 'a) '()) => t

 2. ((eq 'a 'b) '()) => nil

 3. ((cons x '(b c))'((x a ) (y b))) => (a b c)

 4. (((label firstatom (lambda (x)
                                  (cond ((atom x) x)
                                        ('t (firstatom (car x))))))
               y)
             '((y ((a b) (c d))))) => a

 5. ((cons x (cdr y))
             '((x a) (y (b c d)))) => (a b c)

 6.  (((lambda (x) (cons 'a x)) '(b c))
       '((f (lambda (x) (cons 'a x))))) => (a b c)
 
 7. (((label ident (lambda (x) x))
         y)
         '((y ident))) => indent

 8. (((lambda (x) x) '((lambda (x) x))) '()) => (lambda (x) x)

 9. (((label diag (lambda (x) (list x (list 'quote x))))
          y)
        '((y list))) => (list (quote list))

 10. (((label diag (lambda (x) (list x (list 'quote x))))
         y)
       '((y diag))) => (diag (quote diag))

 11. From the original paper og JMC

     (((label ff (lambda (x)
                     (cond ((atom x) x)
                           ('t (ff (car x))))))
         y)
       '((y ((a b) (c d))))) => a
")

(defun not. (x)
  (cond (x '())
        ('t 't)))

(defun null. (x)
  (eq x '()))

(defun and. (x y)
  (cond (x (cond (y't) ('t '())))
        ('t '())))

(defun pair. (x y)
  (cond ((and. (null. x) (null. y)) '())
        ((and. (not. (atom x)) (not. (atom y)))
         (cons (list (car x) (car y))
               (pair. (cdr x) (cdr y))))))

(defun append. (x y)
  (cond ((null. x) y)
        ('t (cons (car x) (append. (cdr x) y)))))

(defun assoc. (x y)
  (cond ((eq (caar y) x) (cadar y))
        ('t (assoc. x (cdr y)))))

(defun eval. (e a)
  (cond
    ((atom e) (assoc. e a))
    ((atom (car e))
     (cond
       ((eq (car e) 'quote) (cadr e))
       ((eq (car e) 'atom)  (atom   (eval. (cadr e) a)))
       ((eq (car e) 'eq)    (eq     (eval. (cadr e) a)
                                    (eval. (caddr e) a)))
       ((eq (car e) 'car)   (car    (eval. (cadr e) a)))
       ((eq (car e) 'cdr)   (cdr    (eval. (cadr e) a)))
       ((eq (car e) 'cons)  (cons   (eval. (cadr e) a)
                                    (eval. (caddr e) a)))
       ((eq (car e) 'cond)  (evcon. (cdr e) a))
       ((eq (car e) 'list) (evlis. (cdr e) a))
       ((eq (car e) 'list) (evlis. (cdr e) a))
       ('t (eval. (cons (assoc. (car e) a)
                        (cdr e))
                  a))))
    ((eq (caar e) 'label)
     (eval. (cons (caddar e) (cdr e))
            (cons (list (cadar e) (car e)) a)))
    ((eq (caar e) 'lambda)
     (eval. (caddar e)
            (append. (pair. (cadar e) (evlis. (cdr e) a))
                     a)))))


(defun evcon. (c a)
  (cond ((eval. (caar c) a)
         (eval. (cadar c) a))
        ('t (evcon. (cdr c) a))))

(defun evlis. (m a)
  (cond ((null. m) '())
        ('t (cons (eval. (car m) a)
            (evlis. (cdr m) a)))))

(defun apply. (f a)
  (eval. (cons f (appq. a)) '()))


(defun appq. (m)
  (cond ((null m) '())
        (t
         (cons (list 'quote (car m)) (appq. (cdr m))))))

(defun lisp ()
    (with-ltk ()
      (wm-title *tk* "LISP")
      (let* ((frame-menus (make-menubar))
             (menu-help (make-menu frame-menus "Help"))
             (f-1 (make-instance 'frame))
             (f-2 (make-instance 'frame))
             (f-3 (make-instance 'frame))
             (f-tutorial (make-instance 'frame))
             (f-eval (make-instance 'frame))
             (f-t-1 (make-instance 'frame))
             (f-t-2 (make-instance 'frame))
             (title-f-1 (make-instance 'label :master f-1 :text "Input box: "))
             (title-f-2 (make-instance 'label :master f-2 :text "Output box: "))

             (input-text (make-instance 'text 
                              :master f-1))
             (output-text (make-instance 'text 
                                         :master f-2))
             (b-clear-in (make-instance 'button
                                     :text "Clear Input"
                                     :master f-3
                                     :width 7
                                     :command (lambda () (clear-text input-text))))
             (b-clear-out (make-instance 'button
                                     :text "Clear Output"
                                     :master f-3
                                     :width 8
                                     :command (lambda () (clear-text output-text))))
                                                         
             (b-eval (make-instance 'button
                                    :text "Eval"
                                    :master f-eval
                                    :width 4
                                    :command (lambda ()
                                               (setf (text output-text) 
                                                     (eval-input-text (read-from-string (text input-text))))))))
        (make-menubutton menu-help "Tutorial" (lambda ()
                                                (let* ((w-about (make-instance 'toplevel  :takefocus nil))
                                                       (txt (make-instance 'scrolled-text :master w-about)))
                                                  (wm-title w-about "Examples")
                                                  (pack txt)
                                                  (setf (text txt) tutorial))))
        (make-menubutton menu-help "About" (lambda ()
                                             (let* ((w-about (make-instance 'toplevel  :takefocus nil))
                                                    (txt (make-instance 'text :master w-about :width 60 )))
                                               (wm-title w-about "About")
                                               (pack txt)
                                               (setf (text txt) "GPLv3 - (c) Tiago Charters de Azevedo <tca@diale.org>"))))

        (pack f-1 :side :top :expand t :fill :both)

        (pack title-f-1 :side :top :expand t :fill :both)               
        (pack input-text)

        (pack f-2 :side :top :expand t :fill :both)      
        (pack title-f-2 :side :top :expand t :fill :both)
        (pack output-text)
        
        (pack f-3 :side :left :expand nil :fill :none)      
        (pack b-clear-in :side :left)
        (pack b-clear-out :side :left)

        (pack f-eval :side :right :expand t :fill :both)
        (pack b-eval :side :right)
        )))

(defun eval-input-text (txt)
  (eval. (car txt) (cadadr txt)))

(lisp)

P.S. 160125: Código LTK actualizado.

Etiquetas/Tags: LISP, John McCarthy, original paper, LTK

Diagonal de Cantor

... quando estou para paródias, dá nisto.

2016/01/21-22:54:21

O argumento da diagonal de Cantor pode ser formulado da seguinte forma. Considere-se T o conjunto de todas as sequências de 0 e 1. Se s1, s2, ..., sn ... é uma enumeração dos elementos de T então existe um elemento de T que não corresponde a nenhuma sequência, i=1,2,... Estranho não?

Estranhamente, repito, o resultado obtém-se de uma forma construtiva. Podemos começar por fazer uma lista (note-se que a ordenação escolhida é totalmente arbitrária e qualquer outra podia ser escolhida sem perda de generalidade)

((0 0 0 0 0 0 0 ...) 
 (1 1 1 1 1 1 1 ...) 
 (0 1 0 1 0 1 0 ...)
 (1 1 0 1 0 1 1 ...)
 (0 0 1 1 0 1 1 ...)
 (1 0 0 0 1 0 0 ...))

Posso assim construir um elemento s de T que não está nessa lista. Como? Tomando o primeiro elemento de s diferente do primeiro elemento de s1, i.e. 1, de seguida o segundo elemento s diferente do segundo elemento de s2, e assim por diante. Viajo pela diagonal e retiro para s um elemento diferente daquele que encontro. s tem então a forma

(1 0 1 1 0 1 ...)

É fácil ver que s não está contido na enumeração inicial que construímos para os elementos de T. E logo que não é possível enumerar todas as sequências de zeros e uns. Falta pelo menos um elemento dessa proposta lista completa.

Não é possível deixar de sentir um certo desconforto que se tem na explicação acima. Admitimos que conseguiríamos enumerar, fazer uma lista de todos as sequências de zeros e uns e depois, de uma foram construtiva, obtemos uma lista extra que não estava contida na lista inicial que nos propusemos construir. A contradição surge de uma forma escandalosa e perturbante e é um sinal de que tomamos uma hipótese que de alguma forma contradiz a nossa habitual forma de ver o mundo e em particular como construímos listas.

Para os matemáticos profissionais (e para mim também, quando não estou para paródias) tal resultado é tomado com muita naturalidade e é uma técnica usada em muitas outras áreas de aplicação.

O facto de T não ser numerável, não conseguirmos fazer uma lista completa, apenas mostra que é sem sentido a afirmação ``consideremos todas as sequências de zeros e uns''. A expressão lista é e si mesma uma variável e não uma coisa com significado primitivo

O paradoxo é sempre o mesmo, em muitas formas surge e reaparece. Mostra bem a nossa confusão sobre tudo isto.

Volte-se então há nossa lista de zeros e uns. Enumerei essa lista na forma s1, s2, ... sn, ... A lista s onde o n-ésimo elemento é dado por

s(n)=1-sn(n)
não está na lista inicial.

Pergunta: é isto uma lei natural? Ou é simplesmente um problema de notação que se revela quando escrevo estas listas de 0's e 1's?

Deve a minha notação prevenir encontrar-me na situação em que me encontro? Que significa pensar que está tudo escrito? A lista foi construída propositadamente para se encontrar o que não lá está. Deve ser isso.

Etiquetas/Tags: Cantor, diagonal

Palavras chave/keywords: página pessoal, blog

Criado/Created: NaN

Última actualização/Last updated: 23-07-2016 [00:02]


GNU/Emacs

1999-2016 (ç) Tiago Charters de Azevedo

São permitidas cópias textuais parciais/integrais em qualquer meio com/sem alterações desde que se mantenha este aviso.

Verbatim copying and redistribution of this entire page are permitted provided this notice is preserved.