/* Copyright (C) Stephen Lee 2007 . * Email:stephen@tachyos.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 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package godel; import java.util.*; import java.awt.*; import java.awt.event.*; import java.applet.*; import javax.swing.*; import javax.swing.plaf.basic.BasicArrowButton; import java.math.*; /**This is an applet to implement a Gödel numbering scheme. * It translates between formal arithmetic statements and positive integers. * For further information see Gödel numbering applet*/ public class godel1 extends Applet implements KeyListener,ActionListener { private static final long serialVersionUID = 1L; public godel1(){} Font cf1; /** Text Area for aritmetic formulae*/ JTextArea txta=new JTextArea(); /**Text Area for Godel Numbers */ JTextArea numed=new JTextArea(); //Label lab1=new Label(); String strin; /** Current position in text*/ int pos; /** Value of (Gödel) number entered. * This is the input bitstream*/ BigInteger numin; /** Set when end of input number reached */ boolean endflg; /** Output text as HTML */ boolean html; /** Press to convert from Gödel numbers to arithmetic formulae*/ BasicArrowButton but1 =new BasicArrowButton(SwingConstants.NORTH); /** Press to convert from arithmetic formulae to Gödel numbers*/ BasicArrowButton but2 =new BasicArrowButton(SwingConstants.SOUTH); final BigInteger THREE=BigInteger.valueOf(3); final BigInteger FOUR=BigInteger.valueOf(4); /** Thrown if text input is not valid */ Error InvInp=new Error("Invalid Input"); /** check if Godel numbers are to be in binary*/ JCheckBox binar=new JCheckBox("binary"); /** Check to wrap number rather than having multiple numbers*/ JCheckBox twrap=new JCheckBox("text-wrap"); /** Check to generate output in the form of HTML (doesn't work for input)*/ JCheckBox ohtml=new JCheckBox("html out"); /** radix - swapped between 10 and 2 */ int radx=10; /** counter which is used to put regular nbsp's into html, to help with wrapping*/ int spct=0; public void keyPressed(KeyEvent e) {} public void keyReleased(KeyEvent e) {} /** replace alt_A with ∀ and > with ⇒*/ public void keyTyped(KeyEvent e) { char c= e.getKeyChar(); int m=e.getModifiers(); if ((m&InputEvent.ALT_MASK)>0){ if (Character.toUpperCase(c)=='A')txta.replaceSelection("\u2200"); else if (c=='>')txta.replaceSelection("\u21D2"); e.consume();}} /** react to up and down buttons, and binary and text-wrap checkbox changes */ public void actionPerformed(ActionEvent e) { int rado; StringTokenizer tok; String res; String ac=e.getActionCommand(); try{ if (ac=="down"){ html=ohtml.isSelected(); txta.setText(""); tok=new StringTokenizer(numed.getText(),"\n"); while (tok.hasMoreTokens()){ numin=new BigInteger(tok.nextToken(),radx); res=wff(); if (numin.compareTo(BigInteger.ONE)!=0) res="ERROR ("+res+")"; txta.append(res+"\n");}} else if (ac=="up"){ tok=new StringTokenizer(txta.getText(),"\n"); numed.setText(""); while (tok.hasMoreTokens()){ strin=tok.nextToken(); pos=0; numin=parse1(); /*n=numin.bitLength(); numin=numin.clearBit(n-1);*/ numed.append(numin.toString(radx)+"\n");}} else if (ac=="binary"){ tok=new StringTokenizer(numed.getText(),"\n"); numed.setText(""); rado=radx; radx=12-radx; while (tok.hasMoreTokens()){ BigInteger pc=new BigInteger( tok.nextToken(),rado); numed.append(pc.toString(radx)+"\n");} } else if (ac=="text-wrap"){ numed.setLineWrap(twrap.isSelected()); } } catch (Error ii){JOptionPane.showMessageDialog(null, "Input not valid");} } /**Set up applet */ public void init() { setLayout(null); setBackground(new Color(230,240,240)); // cf1=new Font("Lucida Sans Unicode",Font.PLAIN,14); cf1=new Font("",Font.PLAIN,14); // add(numed); // numed.setBounds(10,10,200,20); add(but1); but1.setBounds(10,275,40,20); but1.setFont(cf1); add(but2); but2.setBounds(60,275,40,20); JScrollPane scroll1 = new JScrollPane(txta); add(scroll1); JScrollPane scroll2 = new JScrollPane(numed); add(scroll2); txta.setFont(cf1); scroll1.setBounds(10,300,600,250); scroll2.setBounds(10,20,600,250); txta.addKeyListener(this); txta.setLineWrap(true); but2.addActionListener(this); but1.addActionListener(this); but1.getModel().setActionCommand("up"); but2.getModel().setActionCommand("down"); //add(lab1); //lab1.setBounds(110,275,500,20); add(binar); binar.setBounds(10, 5, 60, 15); binar.addActionListener(this); add(twrap); twrap.setBounds(80, 5, 80, 15); twrap.addActionListener(this); add(ohtml); ohtml.setBounds(170, 5, 90, 15); } //-------------------------------- /** Get 2 bits of input bitstream */ int get2(){ endflg=(numin.signum()==0); int result=numin.and(THREE).intValue(); numin=numin.shiftRight(2); return result; } /** Get variable from input bitstream * @return variable in text form */ String getvar(){ int num,n; String sn; num=0; do {n=get2(); if (n<3)num=3*num+n+1;}while (n<3&&!endflg); if (num>=3) sn=String.valueOf(num/3);else sn=""; return String.valueOf((char)('x'+num%3))+sn;} /** Get term from input bitstream * @return term in text form */ String term(int p){ String res; int q=2; boolean isvar=!numin.testBit(0); numin=numin.shiftRight(1); if (isvar)return getvar(); else switch (get2()){ case 0:res="0";break; case 1:res= term(q)+"\'";break; case 2:q=0;res=term(q)+"+ "+term(q);break; default:q=1;res=term(1)+"*"+term(1);} if (p>q)return "("+(html&&spct++%9==0?"  ":" ")+res+")"; else return res; } /** Get formula from input bitstream * @return formula in text form */ String wff(){ switch (get2()){ case 0:return term(0)+"="+term(0); case 1:return (html?"¬":"¬")+wff(); case 2:return "("+wff()+(html?"⇒":"\u21D2")+wff()+")"; case 3:return (html?"∀":"\u2200")+getvar()+" "+wff();} return ""; } //-------------------------------------- /** Gets next character from text */ char nxtch(){ if(pos>=strin.length()) throw InvInp; while (strin.charAt(pos)==' ') pos+=1 ; return strin.charAt(pos++); } /** checks whether current character matches a given one * @param c the character to match * @return true for a match */ boolean chkch(char c){ while (pos=strin.length()||strin.charAt(pos)!=c)return false; pos++;return true; } /** requires current character to match a given one * @param c the character to match */ void chkchv(char c){ if (!chkch(c)) throw InvInp; } /** Translates a text variable into a bitstream form * @param c - the initial letter of the variable * @return bitstream form of variable */ BigInteger getvarn(char c){ BigInteger num=THREE; int n ; n=0; while (pos0){n--; num=num.multiply(FOUR).add(BigInteger.valueOf(n%3)); n/=3;} return num.setBit(num.bitLength());} /** Applies a unary operator to a term or formula. * Also used for operator part of binary operators. * @param op code for operator ' 5,¬ 1 * @param x1 code for input term or formula * @return code for resulting term or formula */ BigInteger unop(int op,BigInteger x1){ int shft; if (op>=4){op=2*op-7;shft=3;} else shft=2; return x1.shiftLeft(shft).add(BigInteger.valueOf(op)); } //------------------- /** Applies a binary operator to a pair of terms or formulae. * * @param x1 first term or formula * @param op code for binary operator * @param x2 second term or formula * @return code for resulting term or formula */ BigInteger binop(BigInteger x1,int op,BigInteger x2){ int n2=x1.bitLength(); BigInteger t=x2.shiftLeft(n2-1).add(x1.clearBit(n2-1)); return unop(op,t); } /**Handles lowest level items in expression * zero, variables and (expression) * @return code for item. */ BigInteger parse6(){ BigInteger cur=BigInteger.ZERO; char c=nxtch(); if (c=='0')return BigInteger.valueOf(9); if (c>='x'&c<='z')return getvarn(c).shiftLeft(1); if (c=='('){cur=parse1();chkchv(')');return cur;} throw InvInp; } /** Handles successor operator * @return code for term */ BigInteger parse5(){ BigInteger cur=parse6(); while(chkch('\''))cur=unop(5,cur); return cur;} /** Handles multiplication * @return code for term */ BigInteger parse4(){ BigInteger cur; cur=parse5(); while (chkch('*'))cur=binop(cur,7,parse5()); return cur;} /** HAndles addition * @return code for term */ BigInteger parse3(){ BigInteger cur; cur=parse4(); while (chkch('+'))cur=binop(cur,6,parse4()); return cur; } /** Handles ∀,¬ and equality * @return code for formula */ BigInteger parse2(){ BigInteger cur; if (chkch('\u2200')){return binop(getvarn(nxtch()),3,parse2());} if (chkch('¬')) return unop(1,parse2()); cur=parse3(); if (chkch('='))return binop(cur,0,parse3()); return cur;} /** Main routine for parsing strin * Handles ⇒ * ⇒ is right associative A⇒B⇒C means A⇒(B⇒C) * @return code for formula */ BigInteger parse1(){ BigInteger cur; cur=parse2(); if (chkch('\u21D2'))return binop(cur,2,parse1()); return cur; } public String getAppletInfo() { return "Godel number"; } }