Groups with Ruby

This image was generated by Vladimir Bulatov’s Polyhedra Stellations Applet: http://bulatov.org/polyhedra/stellation_applet
I’ve started writing some functions for verifying introductory group theory results in order to gain a better understanding of group theory. So far, my Group class is able to determine whether a particular discrete set and operator combination is a group.
Corrections or suggestions for more functionality would be appreciated. I plan on adding functions to calculate cosets and verify Lagrange’s theorem.
class Group def initialize(set, block) @set = set @block = block end def isGroup? has_identity = self.has_identity? is_associative = self.is_associative? is_closed = self.is_closed? has_inverses = self.has_inverses? isGroup = has_identity && is_associative && is_closed && has_inverses if not has_identity p 'No identity' end if not is_associative p 'Not associative' end if not is_closed p 'Not closed' end if not has_inverses p 'Missing inverses' end return isGroup end def is_closed? is_closed = true @set.each do |element| @set.each do |other_element| next_element = @block.call(element, other_element) if not @set.include?(next_element) is_closed = false end end end return is_closed end def has_identity? @set.each do |element| candidate_identity = true @set.each do |other_element| next_element = @block.call(element, other_element) if not next_element == other_element candidate_identity = false end end if candidate_identity == true return true end end return false end def identity has_identity = false @set.each do |element| candidate_identity = true @set.each do |other_element| next_element = @block.call(element, other_element) if not next_element == other_element candidate_identity = false end end if candidate_identity == true return element end end puts 'No identity exists' return nil end def is_associative? is_associative = true @set.each do |a| @set.each do |b| @set.each do |c| element_ab_c = @block.call(@block.call(a, b), c) element_a_bc = @block.call(a, @block.call(b,c)) if not element_ab_c == element_a_bc is_associative = false end end end end return is_associative end def has_inverses? has_inverses = true id = self.identity @set.each do |element| found_inverse = false @set.each do |other_element| next_element = @block.call(element, other_element) if next_element == id found_inverse = true end end if found_inverse == false has_inverses = false end end return has_inverses end end
Unit tests:
require './group' require 'test/unit' class TestGroup < Test::Unit::TestCase def test_add_mod10_int_mod10_isGroup int_mod10 = [0,1,2,3,4,5,6,7,8,9] add_mod10 = Proc.new{ |a,b| (a+b)%10 } add_int_mod10 = Group.new(int_mod10, add_mod10) assert_equal true, add_int_mod10.isGroup? end def test_mult_int_mod10_isNotGroup int_mod10 = [0,1,2,3,4,5,6,7,8,9] mult = Proc.new{ |a,b| a*b } mult_int_mod10 = Group.new(int_mod10, mult) assert_equal false, mult_int_mod10.isGroup? end def test_add_bool_isNotGroup bool = [0,1] add = Proc.new{ |a,b| a+b } add_bool = Group.new(bool, add) assert_equal false, add_bool.isGroup? end def test_add_mod2_bool_isGroup bool = [0,1] add_mod2 = Proc.new{ |a,b| (a+b)%2 } add_mod2_bool = Group.new(bool, add_mod2) assert_equal true, add_mod2_bool.isGroup? end end
Advertisements