게시판 인덱스

 
 FAQFAQ   검색검색   멤버리스트멤버리스트   사용자 그룹사용자 그룹   사용자 등록하기사용자 등록하기 
 개인 정보개인 정보   비공개 메시지를 확인하려면 로그인하십시오비공개 메시지를 확인하려면 로그인하십시오   로그인로그인 

과제 5-1번 질문입니다.

 
이 게시판은 잠겼으므로 글을 올리거나, 답변을 하거나 수정을 할 수 없습니다   이 주제는 잠겼으므로 답변을 하거나 수정을 할 수 없습니다     게시판 인덱스 -> 4190.310 Programming Languages (Fall 2018)
이전 주제 보기 :: 다음 주제 보기  
글쓴이 메시지
신재호



가입: 2018년 9월 13일
올린 글: 10

올리기올려짐: 2018년11월7일 15:55    주제: 과제 5-1번 질문입니다. 인용과 함께 답변

2017 게시판에서

callv에서 Sm5.CALL을 하기 전에 (x,C', E')에서 E'에 자기 자신 f에 대한 것을 저장하는 방식으로 하는게 맞나요? callv에선 함수 이름 f를 받아서 (x,C')에 대한걸 직접적으로 못이용하는데 (x,C', E')에서 E'을 인위적으로 수정하는 방식은 아니죠?
Sm5에서 주어진 연산들을 가지고 생각해보는데 초점을 못 잡겠습니다 ㅜㅜ

라는 질문이 있었는데 똑같은 부분에서 막혀서 질문드립니다.

sm5의 call 명령어를 참고하시면, l :: v :: (x, C, E) 이런식으로 스택에

쌓여있는 정보를 바탕으로 함수를 호출하게 됩니다.

callv를 번역하면 sm5명령어들이 여러개 나올텐데요. 아마 아래와 같은 형태겠지요.

push ... :: push ... ::......... :: call

(정답은 이 예시와 다를수있습니다. 설명을 위한 예시로 참고만해주세요.)

그러면 위 명령어들중 push명령어를 통해 l과 v, (x,C,E)등을 스택에 집어넣게 되고 call을 부르겠지요.

이때 (x, C, E)의 E 안에 재귀를 위한 함수의 정보 자체가 들어갈 수 있게 잘 번역해주면 될것입니다.

-조교 드림.

라고 답변해 주셨습니다. 하지만 LETF에서 (x, C, E)를 f 주소에 집어넣고 난 후에는 E를 기계 안의 명령으로 수정할 방법이 전혀 없습니다. 그러니까 CALLV를 할 때

CALLV (f, e)
라고 하면

***** Environment *****
[f : C, Env = E]

라고 Environment에 저장된 함수를 불러와서 e의 결과값을 변수로 저장한 뒤에 함수를 실행시키는 것으로 이해했습니다. 이때 call 후의 모든 명령과 환경은 K로 저장되고
Environment와 Command는 f 안의 것으로 대체됩니다. 이렇게 되면 call뒤의 명령으로는 E를 바꿀 수 없게 됩니다. 또, 이 전의 명령으로는 (x, C, E)의 값을 개별적으로 변경할 수는 없습니다. 그러면 어떻게 E에 다시 [f:C, Env = E]라는 환경을 저장할 수 있나요? LETF를 건드려야 하는 건가요? 이틀 고민해봤는데 전혀 길을 못찾겠어서 질문드립니다. 힌트라도 제시해주시면 감사하겠습니다. 조교님 항상 감사합니다.
위로
사용자 정보 보기 비밀 메시지 보내기
유진선14



가입: 2018년 9월 11일
올린 글: 18

올리기올려짐: 2018년11월8일 0:45    주제: 인용과 함께 답변

저도 이 문제로 고민하다 해결이 안돼서 부연 질문 남깁니다.

과제에 있는 k.ml (k-- interpreter)을 보면 CALLV 는 다음과 같이 정의되어 있습니다.

코드:
   
      | CALLV (f, arg_exp) ->
      let (arg_v, mem') = eval mem env arg_exp in
      let (arg_id, e_body, env_saved) = lookup_env_proc env f in
      let (l, mem'') = Mem.alloc mem' in
      let env' = Env.bind env_saved arg_id (Addr l) in
      let new_mem = Mem.store mem'' l arg_v in
 [b]     (* Now, bind procedure 'f', to support recursion *)[/b]
      let env'' = Env.bind env' f (Proc (arg_id, e_body, env_saved)) in
      eval new_mem env'' e_body




이 부분을 보면 e_body를 eval 하기 전에 env 를 env''로 바꿔줘야 하며, 이때 env''는 x-l, f->(x, e', env') 가 각각 binding 되어있어야 하는 것으로 보입니다. 특히, f->(x, e', env')는 코멘트에서 따로 강조하듯 recursion을 위해 binding을 별도로 반드시 진행해야 하는 것으로 보입니다.

이를 SM5로 바꾼다면
S M E C K 를
S M{l->v}______(f, (x, C', E'))::(x,l)::E'______C'______(C, E)::K
(수정할땐 긴 공백인 부분이 게시할때는 다 사라져서 underbar를 넣었습니다)
로 바꾸는 과정이 될것으로 보입니다.

그러나 M을 M{l->v}로, E를 (x,l)::E'로 바꾸는 과정인 Sm5.CALL은 CALL전에 E'에 무슨 짓을 해도 C'가 (x,l)::E' 환경에서만 실행하게만듭니다. 만일 원하는대로 (f, (x, C', E'))::(x,l)::E' 에서 C'를 실행하게 하고 싶으면 처음에 l::v::(x,C',E')::S를 쌓을때부터 E'에 f->(x,C',E')가 포함되게 해야 할 것 같은데, Sm5명령으로 기계의 상태를 바꾸지 못하기 때문에 어떻게 해야할지 고민입니다.

최초로 함수 콜을 할때는 환경에서 (f, (x,C',E'))를 불러올 일이 없으니 별 문제가 되지는 않지만, 재귀를 하려고 하면 막혀서 전혀 되지를 않습니다..
혹시 잘못 이해한 것이 있을까요?

항상 감사드립니다.


유진선14 가 2018년11월8일 9:12에 수정함, 총 2 번 수정됨
위로
사용자 정보 보기 비밀 메시지 보내기
유진선14



가입: 2018년 9월 11일
올린 글: 18

올리기올려짐: 2018년11월8일 1:15    주제: 인용과 함께 답변

임의로 sm5.ml의

코드:
   | (V (L l) :: V v :: P (x, c', e') :: s, m, e, CALL :: c, k) ->
      (s, store l v m, (x, Loc l) :: e', c', (c, e) :: k)


코드:
    | (V (L l) :: V v :: P (x, c', e') :: s, m, e, CALL f :: c, k) ->
      (s, store l v m, (f, Proc (x, c', e') ) :: (x, Loc l) :: e', c', (c, e) :: k)

로 바꾸(고 constructor CALL이 string을 input으로 받게 수정했) 었더니 문제가 해결되었습니다. sm5.ml을 바꾸지 않고, 정의된 sm5명령만으로 이런 효과를 낼 수 있는 방법이 있을까요?

감사합니다!!
위로
사용자 정보 보기 비밀 메시지 보내기
강태호



가입: 2018년 9월 10일
올린 글: 9

올리기올려짐: 2018년11월8일 9:33    주제: 인용과 함께 답변

전 명령어 실행 자체를 건드리지 않고 주어진 명령어로도 해결이 가능했네요

"이때 (x, C, E)의 E 안에 재귀를 위한 함수의 정보 자체가 들어갈 수 있게 잘 번역해주면 될것입니다. "라고 조교님이 적어주신것에서 저는 스택에 있는 E 자체는 변화시키지 않고 해서 맞게 구현한건지 모르겠네요
저는 따로 함수의 정보를 전달했어요
위로
사용자 정보 보기 비밀 메시지 보내기
배요한
Site Admin


가입: 2018년 3월 6일
올린 글: 107

올리기올려짐: 2018년11월8일 14:39    주제: 인용과 함께 답변

안녕하세요,

LETF와 CALLV 번역이 원래 가장 어려운 부분입니다.
나중에 알고 나면 의외로 간단해서 허탈해지는 반면, 처음에는 약간의 발상의 전환이 필요합니다.

임의로 sm5.ml의 코드를 바꾸면 안 됩니다. 하지만, 기본적으로 정의된 명령만으로도 원하는 효과를 이루는 방법은 있습니다.

힌트를 드리자면,
1) 스택에서 svalue를 꺼내는 커맨드를 호출하기 전에는, 스택에서 사라지지 않는 성질을 이용하여
2) CALL 할 때도 살짝 무언가를 추가적으로 해주면 됩니다.


답글을 통해 수강생들끼리 서로 고민해 보고 해결해 나갈 수 있길 바랍니다.

감사합니다.

TA 이동권
e-mail: dklee@ropas.snu.ac.kr

TA 배요한
e-mail: yhbae@ropas.snu.ac.kr
위로
사용자 정보 보기 비밀 메시지 보내기
신재호



가입: 2018년 9월 13일
올린 글: 10

올리기올려짐: 2018년11월8일 16:04    주제: 인용과 함께 답변

강태호 씀:
전 명령어 실행 자체를 건드리지 않고 주어진 명령어로도 해결이 가능했네요

"이때 (x, C, E)의 E 안에 재귀를 위한 함수의 정보 자체가 들어갈 수 있게 잘 번역해주면 될것입니다. "라고 조교님이 적어주신것에서 저는 스택에 있는 E 자체는 변화시키지 않고 해서 맞게 구현한건지 모르겠네요
저는 따로 함수의 정보를 전달했어요


함수의 정보를 따로 전달했다는 것이 무슨 의미인지 잘 모르겠습니다. 좀 더 자세히 설명해 주실 수 있나요?
위로
사용자 정보 보기 비밀 메시지 보내기
신재호



가입: 2018년 9월 13일
올린 글: 10

올리기올려짐: 2018년11월8일 16:36    주제: 해결했습니다!!!!!!!!! 인용과 함께 답변

해결했습니다!!!!!!!!!ㅜㅜㅜㅜㅜㅜㅜ 조교님 정말 진심으로 감사드립니다...

아직 해결하지 못한 분께 힌트를 드리자면,

"call 명령을 실행시켜도 Svalue의 값은 바뀌지 않습니다!!"

이를 명심하면서 LETFCALLV의 코드를 짜면 될 것 같습니다. 극한의 발상의 전환이 필요합니다.

저처럼 사흘동안 헛고생하는 일이 없도록 이 글이 많은 분께 도움이 됐으면 좋겠습니다.
위로
사용자 정보 보기 비밀 메시지 보내기
유진선14



가입: 2018년 9월 11일
올린 글: 18

올리기올려짐: 2018년11월9일 3:27    주제: 인용과 함께 답변

저도 해결했습니다!ㅜㅜㅜㅜㅜ 조교님 힌트에 정말로 감사드립니다 ㅠㅠㅠㅠ

저도 힌트를 드린다...기보다 거듭 강조하자면,
"LETF CALLV 번역이 원래 가장 어려운 부분입니다."

를 보시면 될거같습니다.
발상의 전환이라는 말씀..이 정말 사실이더군요 :idea:
저는 이제 for 룹을 해결하러 가보겠습니다... 모두 화이팅하세요..!
위로
사용자 정보 보기 비밀 메시지 보내기
정윤수



가입: 2018년 9월 11일
올린 글: 2

올리기올려짐: 2018년11월15일 23:05    주제: 인용과 함께 답변

저도 몇 일간 고민하다가 위 글에서 도움받아서 해결했습니다.
혹시라도 아직 고민하고 계시는 분이 계시다면
당연한 말일 수도 있지만 제가 잘 생각하지 못했던 부분을 공유합니다.

f(x) = x + f(x - 1) 리컬시브 함수라고 가정했을 때
f(x)는 K.CALLV에서 환경 E에서 실행된다고 한다면,
f(x-1)이 부르는 K.CALLV은 E위에서 실행된다는 점을 떠올릴수 있다면 조금 더 쉬웠을 것 같습니다.

반면 Sm5.CALL은 f가 (f,(x, C, f_E)) :: E에서 정의된 f_E를 부른다는 점.
Sm5.CALL과 K.CALLV가 실행되는 차이를 생각하는 게 저한테는 유효했습니다.

누군가에게 도움이 되기를 바라면서 적어봅니다.
위로
사용자 정보 보기 비밀 메시지 보내기
이전 글 표시:   
이 게시판은 잠겼으므로 글을 올리거나, 답변을 하거나 수정을 할 수 없습니다   이 주제는 잠겼으므로 답변을 하거나 수정을 할 수 없습니다     게시판 인덱스 -> 4190.310 Programming Languages (Fall 2018) 시간대: GMT + 9 시간(한국)
페이지 11

 
건너뛰기:  
새로운 주제를 올릴 수 없습니다
답글을 올릴 수 없습니다
주제를 수정할 수 없습니다
올린 글을 삭제할 수 없습니다
투표를 할 수 없습니다


Powered by phpBB 2.0.21-7 (Debian) © 2001, 2005 phpBB Group
Translated by kss & drssay