Требуется отметка подтипа Ады

Мне дали проект в универе, где мне нужно написать ADA-пакет графа. Точки графа хранятся в массиве, ребра хранятся в матрице. (В матрице, если между двумя точками есть ребро, число в этом индексе является весом/длиной ребра)

Необходимы две процедуры: NewPoint и NewEdge.

Необходимы три функции: IsItaPoint, IsitAnEdge и print (матрица и массив).

Я начал изучать ADA неделю назад, и я уверен, что для некоторых из вас это двухминутный код. Я написал это:

Граф.объявления

package Graph is 
function IsItAPoint (G: Graph;I: Integer) return Boolean;
function IsItAnEdge (G: Graph;I: Integer; J: Integer ) return Boolean;


procedure NewEdge (G: Graph;I: Integer; J: Integer; S: Integer); 
procedure NewPoint(G: Graph;I: Integer);


type PointArray is array(Integer range <>) Of Integer;
type EdgeMatrix is array(Integer range <>,
                    Integer range <>) of INTEGER;
PointCount: Integer:=0;


end Graph;

График.adb

package body Graph is

procedure NewPoint(G: Graph;I: Integer) is
begin
    G.PointCount:=G.PointCount+1;
    G.PointArray(G.PointCount):=I;
end;

procedure NewEdge(G: Graph;I: Integer; J: Integer; S: Integer) is
begin
    G.EdgeMatrix(I,J):=S;
end;

function IsItAPoint (G: Graph;I: Integer) return Boolean is 
begin
    for J in 1..100 loop
        if (G.PointArray(J)=I) then return True; end if;
    end loop;
    return False;
end;


function IsItAnEdge (G: Graph;I: Integer; J: Integer ) return Boolean is
begin
    return (G.EdgeMatrix(I,J)=Null);
end;

end Graph;

Я получаю сообщение об ошибке «Граф не виден» и «в этом контексте требуется отметка подтипа» в файле adb.

Можете ли вы помочь мне исправить все это дело?


person Dorrektor125    schedule 31.10.2015    source источник
comment
Вероятно, у вас есть тип (или подтип) под названием Graph, объявленный где-то еще, предположительно в другом пакете, да? Добавьте эту спецификацию пакета в Q. Кроме того, оставляя в стороне мудрость повторного использования имени типа для пакета, было бы полезно указать, какая строка в graph,adb сообщает об ошибке. Я предполагаю, что объявление типа для Graph просто не видно, потому что для этого пакета нет предложения With или Use.   -  person user_1818839    schedule 31.10.2015
comment
См. этот ответ для «требуется отметка подтипа». Кроме того, я бы рекомендовал называть пакет Graphs; тогда вы можете добавить недостающее type Graph is ... без путаницы.   -  person Simon Wright    schedule 31.10.2015
comment
Пожалуйста, скопируйте и вставьте точное сообщение об ошибке в свой вопрос. Я предполагаю, что фактическое сообщение было «График не виден», а не «Граф не виден». Незначительные орфографические ошибки, подобные этой, могут быть очень значительными.   -  person Keith Thompson    schedule 01.11.2015


Ответы (1)


Хорошо, глядя на код до сих пор, я думаю, что вы можете ошибочно принять Package за замену C++ Class, тогда как на самом деле это больше похоже на C++ Namespace.

В C++ не было пространств имен, когда я впервые использовал его, но они настолько хорошо организуют принцип, что я добавил их позже. Напротив, пакеты были оригинальной частью Ады.

Теперь C++ Class (или Struct, или Union) будет отображаться на Ada Record. Если он стоит отдельно, это может быть простая запись, но если она предназначена для наследования, это будет Tagged Record. Tagged Record, разрешающий наследование, не был частью Ады-83, он был добавлен 20 лет назад в Аде-95.

И типичной практикой было бы обернуть Record и все его видимые извне операции в Package.

Итак, я думаю, вы ищете что-то вроде:

package Graph_Pkg is 

type Graph is tagged private; -- hide everything about the actual record!

function IsItAPoint (G: Graph;I: Integer) return Boolean;
function IsItAnEdge (G: Graph;I: Integer; J: Integer ) return Boolean;

procedure NewEdge (G: in out Graph;I: Integer; J: Integer; S: Integer); 
procedure NewPoint(G: in out Graph;I: Integer);

-- PointCount: Integer:=0; -- moved to package body
function PointCount return Integer;

private
-- Everything below here is hidden from package users

type PointArray is array(Integer range <>) Of Integer;
type EdgeMatrix is array(Integer range <>,
                    Integer range <>) of INTEGER;

type Graph is tagged record
   -- here the member variables are declared
   Points : PointArray;
end record;

end Graph_Pkg;

Теперь все детали реализации находятся в теле.

package body Graph_Pkg is

-- The equivalent of C++ "static members" can be declared here
PointCount: Integer:=0;

-- and add the subprogram implementations here

end Graph_Pkg;

Если вы хотите, чтобы количество точек на графике было переменным после того, как график был построен, я вижу проблемы в реализации. Возможно, вы захотите взглянуть на классы контейнеров Ada-2005 для этого.

person user_1818839    schedule 31.10.2015
comment
Брайан, это было очевидное изменение - также я думаю, что Graph должен содержать EdgeMatrix, чтобы быть ограниченным (максимальным количеством?) точек и ребер и содержать текущее количество точек и ребер. - person Simon Wright; 01.11.2015
comment
Я уверен, что он должен содержать EdgeMatrix, я просто хотел указать правильный способ организации вещей. И я не хотел вдаваться в подробности определения размеров матриц, хотя, судя по тому, что я вижу в дизайне, они, вероятно, лучше всего реализуются с использованием классов-контейнеров. В противном случае впереди крутая кривая обучения, включающая либо размеченные записи, либо типы доступа... - person user_1818839; 01.11.2015